본 시리즈는 인프런 강의 함수형 프로그래밍과 JavaScript ES6+ ( 지식 공유자 : 유인동 님 ) 의 강의를 수강하면서 내용을 제 방식대로 포스팅하는 글입니다.
함수형 프로그래밍과 JavaScript ES6+ - 인프런 | 강의
ES6+와 함수형 프로그래밍을 배울 수 있는 강의입니다. 이 강좌에서는 ES6+의 이터러블/이터레이터/제너레이터 프로토콜을 상세히 다루고 응용합니다. 이터러블을 기반으로한 함수형 프로그래밍,
www.inflearn.com
이 내용은 이전 게시물과 이어집니다.
앞서 작성한 go() 함수에 이어서, pipe() 라는 함수를 만들어 볼것이다.
pipe() 는 go() 함수와 다르게 '함수를 리턴하는 함수' 이다.
go() 함수는 즉시 함수들과 인자를 전달해서 바로 어떤값을 평가하는데 사용한다면,
pipe() 함수는 나열된 함수들이 합성된 함수이다.
먼저 pipe() 함수가 어떻게 동작해야할지 시뮬레이션 해보자.
const go = (...argus: any[]) => reduce((value, fn) => fn(value), argus); // 111
const pipe = () => {};
// pipe 함수를 사용하면 이런식으로 사용되게 된다.
// 연속적으로 실행되는 함수를 축약해서 함수로 리턴하는 것이다.
const fn_1 = pipe(
(a: number) => a + 1,
(a: number) => a + 10,
(a: number) => a + 100
);
따라서 pipe() 는 함수를 리턴하는 함수다.
const pipe = () => () => {};
// 따라서 이 함수를 원할때 실행하면 go() 에서 구현한 것과 동일한 값이 나오도록 구현해보자.
log(fn_1(0)); // 111
go([
0,
(a: number) => a + 1,
(a: number) => a + 10,
(a: number) => a + 100,
log,
]); // 111
이제 pipe() 를 구현하는 일만 남았다.
// 결국 이 pipe 함수는 내부적으로 go() 를 사용하는 함수라고 볼수있다.
// 함수들을 인자로 전달받고, 나중에 실행할 인자를 받는 형태이다.
const pipe =
(...functions: ((value: number) => number)[]) =>
(value: number) =>
go(value, ...functions);
const fn_1 = pipe(
(a: number) => a + 1,
(a: number) => a + 10,
(a: number) => a + 100
);
log(fn_1(0)); // 111
너무 간단하게 pipe() 함수가 구현되어 버렸다.
타입스크립트로 작성하다가 발견한 것인데, 매개변수를 여러개로 받아 rest 문법을 적용하면
타입스크립트에서 이 매개변수 자체를 배열 ( Array<any> / any[ ] ) 형태로 취급하는것 같다.
매개변수를 배열로 전달하는것이 아닌, 여러개의 매개변수를 ...rest 하기위해 배열의 형태로 취급 '만' 하는 것이고,
실제로는 func( a, b, c, d ) 형태로 쓸수 있는것이다.
pipe 함수 에는 go 함수와 다르게 좀더 기능을 추가해보자.
예를 들어 add 함수 (값을 더하는 함수) 가 있다고 했을때, go 함수의 경우 시작하는 첫 인자가 두개여야 할 경우
// 이런식으로 하면
go([
add(0, 1), // 1 로 평가되어진다.
(a: number) => a + 10,
(a: number) => a + 100,
log,
]); // 111
같은 형태로 pipe() 를 사용해 구현 하려면
const fn_2 = pipe(
(a: number) => a + 10,
(a: number) => a + 100
);
log(fn_2(add(0, 1))); // 111
이와 같이 add 를 해서 전달해야해서 조금 아쉽다.
따라서 첫번째 함수의 경우에는 인자를 두개이상 받아서 전달할수 있도록 구성해보면 좋을것 같다.
// 이와 같이 사용하고 싶은 것 이다.
const fn_2 = pipe(
(val1, val2) => val1 + val2,
(a: number) => a + 10,
(a: number) => a + 100
);
log(fn_2(0, 1)); // 111
이제 구현해보자
// fn_2 가 받을 인자를 여러개의 인자로 받도록 하고
// go 가 시작하는 부분에서 첫번째 함수에 여러개의 인자를 받고,
// 그다음 함수들이 실행되도록 하면 된다.
const pipe =
(
// 이런식으로 함수를 하나 인자로 받아오면
// 첫번째 함수만 꺼내고 나머지 함수들은 뒤에 따라오게 된다.
fn: (...values: number[]) => number,
...functions: ((value: number) => number)[]
) =>
// 반환할 함수에 여러개의 인자를 받고
(...value: number[]) =>
// go 를 시작하는 부분을 add(0, 1) 처럼 첫번째 함수의 인자를 펼쳐서 전달 하면 된다.
go(fn(...value), ...functions);
const fn_2 = pipe(
(val1, val2) => val1 + val2,
(a: number) => a + 10,
(a: number) => a + 100
);
log(fn_2(0, 1)); // 111
이로써 첫번째 함수는 여러개의 매개변수로 사용할수있는 pipe() 함수가 되었다.
'Javascript' 카테고리의 다른 글
JS 에서의 Symbol 의 사용과 응용 (0) | 2022.09.30 |
---|---|
JS 에서 Symbol 이란? (0) | 2022.09.29 |
reduce 를 이용한 함수 go() 를 구현해보자 - JS ES6+ 함수형 프로그래밍 - 18 (0) | 2022.09.27 |
map + filter + reduce 중첩 사용과 함수형 사고 - JS ES6+ 함수형 프로그래밍 - 17 (0) | 2022.09.27 |
reduce 함수를 구현해보자 2 - JS ES6+ 함수형 프로그래밍 - 16 (0) | 2022.09.27 |