pipe는 가변인수 형식으로 동작한다. 어떤 타입의 함수가 인자로 들어올지 알 수 없으므로 Function
타입으로 정의해야 한다.
pipe 함수의 반환값 역시 함수
다. 반환되는 함수의 타입도 알수 없으므로 제네럴한 Function
타입으로 지정한다
const pipe = (...functions: Function[]): Function
조합된 결과로 반환되는 함수의 애리티가 1이므로 이를 구현하면 아래와 같고, 다음과 같이 해석할 수 있다.
함수
. 값이 아니라 함수가 반환된다.const pipe = <T, R>(...functions: Function[]): Function =>
(x: T) => (T) => R
이제 위의 2번 설명에서 반환되는 함수의 몸통을 구현해야 한다.
pipe함수의 입력으로 받는 x는 reduce의 초기값으로 설정되므로 이 매개변수를 기준으로 리듀가 호출된다. reduce 콜백함수 안의 func는 functions배열의 원소가 순차적으로 반영되며 value는 accumulator로 계산결과가 누적되어 최종적으로 값을 반환한다.
const pipe = <T, R>(...functions: Function[]): Function =>
(x: T) => (T) => R => {
return functions.reduce((value, func) => func(value), x)
}
compose함수도 functions배열에 reverse()를 적용하면 pipe와 유사하게 구현가능하다. 다만 순수함수여야 하므로 spread operator로 deepcopy한 배열에다 reverse()를 호출하고 deepcopied한 배열을 대상으로 reduce를 호출해야되는 점을 기억해야 한다.