関数プログラミングの使用例

24073 ワード


この文章は劉仁東の関数式プログラミングの授業内容を整理した.
前に作成した次の関数を使用して例を解きます.
  • go関数
  • pipe関数
  • curry関数
  • (mapfilterreduce)+curry関数
  • まず、以前に完了したコードを見てみましょう.
    // go 함수
    const go = (...args) => reduce((a, f) => f(a), args);
    
    // pipe 함수
    const pipe =
      (f, ...fs) =>
      (...as) =>
        go(f(...as), ...fs);
    
    // curry
    const curry =
      f =>
      (a, ...agrs) =>
        agrs.length ? f(a, ...agrs) : (...agrs) => f(a, ...agrs);
    
    // map + curry
    const map = curry((f, iter) => {
      const res = [];
      for (const el of iter) {
        res.push(f(el));
      }
      return res;
    });
    
    // filter + curry
    const filter = curry((f, iter) => {
      let res = [];
      for (const a of iter) {
        if (f(a)) res.push(a);
      }
      return res;
    });
    
    // reduce + curry
    const reduce = curry((f, acc, iter) => {
      if (!iter) {
        iter = acc[Symbol.iterator]();
        acc = iter.next().value;
      }
      for (const a of iter) {
        acc = f(acc, a);
      }
      return acc;
    });
    次に、実装した関数を用いて、以下に示すデータを加工します.
    // 예제, products
    const products = [
      { name: '반팔티', price: 15000, quantity: 1, isSelected: true },
      { name: '긴팔티', price: 20000, quantity: 2, isSelected: false },
      { name: '핸드폰케이스', price: 15000, quantity: 3, isSelected: true },
      { name: '후드티', price: 30000, quantity: 4, isSelected: false },
      { name: '바지', price: 25000, quantity: 5, isSelected: false },
    ];
    利用できるのは以下の通りです.
    const add = (a, b) => a + b;
    
    const sum1 = (f, iter) => go(iter, map(f), reduce(add));
    // sum1 함수는 map(p => p.quantity) -> reduce(add)를 추상화한 함수이다.
    // 즉 특정 조건으로 맵핑한후 합치는 함수이다.
    
    const sum2 = curry((f, iter) => go(iter, map(f), reduce(add)));
    // sum2 함수는 sum1함수에서 커링을 한 버전으로 사용될 때 더욱 간결하게 사용할 수 있다.
    
    // product 총 수량
    const totalQuantity1 = pipe(
      map(p => p.quantity),
      reduce(add)
    );
    console.log(totalQuantity1(products)); // 15
    
    // product 총 수량, sum함수로 추상화
    const totalQuantity2 = products => sum1(p => p.quantity, products);
    console.log(totalQuantity2(products)); // 15
    
    // product 총 수량, sum함수로 추상화, 커링
    const totalQuantity3 = sum2(p => p.quantity);
    console.log(totalQuantity3(products)); // 15
    
    // product 총 가격
    const totalPrice1 = pipe(
      map(p => p.price * p.quantity),
      reduce(add)
    );
    console.log(totalPrice1(products)); // 345000
    
    // product 총 가격, sum함수로 추상화
    const totalPrice2 = products => sum1(p => p.price * p.quantity, products);
    console.log(totalPrice2(products)); // 345000
    
    // product 총 가격, sum함수로 추상화, 커링
    const totalPrice3 = sum2(p => p.price * p.quantity);
    console.log(totalPrice3(products)); // 345000
    
    // sum2 함수는 product뿐아니라 다양한 데이터에 사용할 수 있도록 추상화가 되었다.
    // 예제, user
    const user = [
      { name: 'lia', age: 20 },
      { name: 'kyle', age: 25 },
      { name: 'spancer', age: 30 },
      { name: 'sun', age: 30 },
      { name: 'elly', age: 35 },
    ];
    
    // 모든 user의 나이의 총 합
    console.log(sum2(user => user.age, user)); // 140
    console.log(sum2(user => user.age)(user)); // 140