함수형 프로그래밍 기본 함수2

김준엽·2022년 7월 5일
0

저번 시간에 구현한 함수를 응용해서 사용할 수 있는 함수 go, pipe, curry를 구현하고 사용법을 알아보겠습니다.

go

전달 인자로 받은 함수를 차례대로 실행시키는 함수입니다. reduce 함수를 이용해서 구현합니다.

// go 함수 구현
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 go = (...args) => reduce((a, f) => f(a), args)

// go 함수 사용
go(
  0,
  (a) => a + 1,
  (a) => a + 10,
  (a) => a + 100,
  console.log
) // 111

const result = go(
  0,
  (a) => a + 1,
  (a) => a + 10,
  (a) => a + 100
)
console.log(result) // 111

pipe

함수를 합성하는 함수입니다. go 함수를 이용해서 구현합니다.

[예제 1] go 함수 코드

const result = go(
  0,
  (a) => a + 1,
  (a) => a + 10,
  (a) => a + 100
)
console.log(result) // 111

위 코드에서 pipe 함수를 구현해서 사용해보겠습니다.

[예제 2] pipe 함수 코드

const pipe = (...fs) => (a) => go(a, ...fs)

const f = pipe(
  (a) => a + 1,
  (a) => a + 10,
  (a) => a + 100
)
console.log(f(0)) // 111

pipe 함수는 인자로 받은 함수를 합성합니다. go 함수를 대체할 수 있고 pipe 함수 결과값으로 인자를 받을 수 있습니다.

[예제 3] 인자 2개를 못받는 기존 pipe 결과함수

const add = (a, b) => a + b

go(
  add(0, 1),
  (a) => a + 10,
  (a) => a + 100,
  console.log
) // 111

const f = pipe(
  add,
  (a) => a + 10,
  (a) => a + 100
)
console.log(f(2, 7)) // NaN

인자를 2개로 받는 함수는 지금의 pipe 함수로 정상적으로 실행하지 못합니다. pipe 함수를 보강해보겠습니다.

[예제 4] 인자 2개를 받을 수 있는 pipe 결과함수

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

const add = (a, b) => a + b

const f = pipe(
  add,
  (a) => a + 10,
  (a) => a + 100
)
console.log(f(2, 7)) // 119

const f2 = pipe(
  (a) => a + 1,
  (a) => a + 10,
  (a) => a + 100
)
console.log(f2(9)) // 120

인자를 2개를 받을 수 있고 인자 1개도 문제 없이 받습니다.


curry

커링(curring)하는 함수입니다. 커링은 f(a, b, c)처럼 단일 호출로 처리하는 함수를 f(a)(b)(c)와 같이 각각의 인수가 호출 가능한 프로세스로 호출된 후 병합되도록 변환하는 것입니다.

const curry = f =>
		(a, ..._) => _.length ? f(a, ..._) : (..._) => f(a, ..._)

const mult = curry((a, b) => a * b)
console.log(mult(3)) // (..._) => f(a, ..._)
console.log(mult(3, 2)) // 6
console.log(mult(3)(2)) // 6

이 curry 함수는 전달 인자 2개까지 커링할 수 있습니다.

profile
프론트엔드 개발자

0개의 댓글