September 25, 2023
const map = (f, iter) => {
  let res = []
  for (const a of iter) {
    res.push(f(a))
  }
  return res
}
// ... 사용 예시
log(map(p => p.name, products))const filter = (f, iter) => {
  let res = []
  for (const a of iter) {
    if (f(a)) res.push(a)
  }
  return res
}
// ... 사용 예시
log(filter(p => p.price < 20000, products))const reduce = (f, acc, iter) => {
  if (!iter) {
    iter = acc[Symbol.iterator]()
    acc = iter.next().value
  }
  for (const a of iter) {
    acc = f(acc, a)
  }
  return acc
}
// ... 사용 예시
const add = (a, b) => a + b
log(reduce(add, 1, [2, 3, 4, 5]))
log(reduce(add, [1, 2, 3, 4, 5]))const products = [
  { name: '반팔티', price: 15000 },
  { name: '긴팔티', price: 20000 },
  { name: '핸드폰케이스', price: 15000 },
  { name: '후드티', price: 30000 },
  { name: '바지', price: 25000 },
]
const add = (a, b) => a + b
log(
  reduce(
    add,
    map(
      p => p.price,
      filter(p => p.price < 20000, products)
    )
  )
)
log(
  reduce(
    add,
    filter(
      n => n >= 20000,
      map(p => p.price, products)
    )
  )
)const go = (...args) => reduce((a, f) => f(a), args)
// ... 사용 예시
go(
  0,
  a => a + 1,
  a => a + 10,
  a => a + 100,
  log // 111
)const pipe = (f, ...fs) => (...as) => go(f(...as), ...fs)
// ... 사용 예시
const f = pipe(
  (a, b) => a + b,
  a => a + 10,
  a => a + 100
)
log(f(0, 1))const add = (a, b) => a + b
log(
  reduce(
    add,
    map(
      p => p.price,
      filter(p => p.price < 20000, products)
    )
  )
)const add = (a, b) => a + b
go(
  products,
  products => filter(p => p.price < 20000, products),
  products => map(p => p.price, products),
  prices => reduce(add, prices),
  log
)const curry = f => (a, ..._) => (_.length ? f(a, ..._) : (..._) => f(a, ..._))const map = curry((f, iter) => {
  let res = []
  for (const a of iter) {
    res.push(f(a))
  }
  return res
})
const filter = curry((f, iter) => {
  let res = []
  for (const a of iter) {
    if (f(a)) res.push(a)
  }
  return res
})
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
})const add = (a, b) => a + b
go(
  products,
  products => filter(p => p.price < 20000, products),
  products => map(p => p.price, products),
  prices => reduce(add, prices),
  log
)const add = (a, b) => a + b
go(
  products,
  products => filter(p => p.price < 2000)(products),
  products => map(p => p.price)(products),
  prices => reduce(add)(prices),
  log
)
// 최종
go(
  products,
  filter(p => p.price < 2000),
  map(p => p.price),
  reduce(add),
  log
)