파트5. 코드를 값으로 다루어 표현력 높이기 - ChoDragon9/posts GitHub Wiki

go

즉시 전달받은 값을 평가합니다.

const go = (...args) => reduce((a, f) => f(a), args);
go(
  0,
  a => a + 1,
  a => a + 10,
  a => a + 100,
  console.log
);
// output: 111

pipe

const pipe = (f, ...fs) => (...args) => go(f(...args), ...fs)

pipe(
  a => a + 1,
  a => a + 10,
  a => a + 100,
  console.log
)(0);

go를 사용하여 읽기 좋은 코드로 만들기

go(
  products,
  products => filter(p => p.price < 20000, products),
  products => map(p => p.price, products),
  products => reduce(add, products)
);

curry

const curry = f => (a, ..._) => {
  return _.length ? f(a, ..._) : (..._) => f(a, ..._);
}
const map = curry((iteratee, iterable) => {
  const res = [];
  for (const a of iterable) {
    res.push(iteratee(a));
  }
  return res;
})
const filter = curry((predicate, iterable) => {
  const res = [];
  for (const a of iterable) {
    if (predicate(a)) res.push(a);
  }
  return res;
})
const reduce = curry((reducer, accumulator, iterable) => {
  if (!iterable) {
    iterable = accumulator[Symbol.iterator]();
    accumulator = iterable.next().value;
  }
  for (const a of iterable) {
    accumulator = reducer(accumulator, a);
  }
  return accumulator;
})
go(
  products,
  filter(p => p.price < 20000),
  map(p => p.price),
  reduce(add),
  console.log
);
// output: 30000

함수 조합으로 함수만들기

go(
  products,
  filter(p => p.price >= 20000),
  map(p => p.price),
  reduce(add),
  console.log
);

go(
  products,
  filter(p => p.price < 20000),
  map(p => p.price),
  reduce(add),
  console.log
);

아래와 같이 중복을 제거할 수 있습니다.

const baseTotalPrice = pred => pipe(
  filter(pred),
  map(p => p.price),
  reduce(add)
)

go(
  products,
  baseTotalPrice(p => p.price >= 20000),
  console.log
);

go(
  products,
  baseTotalPrice(p => p.price < 20000),
  console.log
);