JavaScript/함수형 프로그래밍과 JavaScript ES6+

코드를 값으로 다루어 표현력 높이기(pipe)

느리지만 꾸준하게 2021. 8. 19. 18:14

pipe함수는 go함수와 다르게 함수를 return하는 함수인데 go함수는 즉시 함수들과 인자들을 전달해서 평가하는데 사용한다면 pipe는 함수는 함수들이 나열되어 있는 합성된 함수를 만드는 함수이다. pipe를 빈함수로 만들어준다.

    const go = (...args) => reduce((a, f) => f(a), args);
    const pipe = () => {};

    go(
        0,
        a => a + 1,
        a => a + 10,
        a => a + 100,
        log);

f라는 함수를 pipe를 통해서 만드는데 코드를 전달해서 a가 있는 세 개의 함수를 연속적으로 실행하면서 축약하는 하나의 함수를 만들어서 함수를 f에다가 리턴한다. 즉 pipe함수는 함수를 리턴하는 함수이다. 로그를 실행하면서 f를 전달하면 똑같이 값이 만들어지는 함수를 만들어보도록 하자.

const pipe = () => () => {};
<script>
    const go = (...args) => reduce((a, f) => f(a), args);
    const pipe = () => () => { };

    go(
        0,
        a => a + 1,
        a => a + 10,
        a => a + 100,
        log);

    const f = pipe(
        0,
        a => a + 1,
        a => a + 10,
        a => a + 100);

    log(f(0));
</script>

pipe함수는 내부적으로 go를 쓰는 함수라고 볼 수 있다. 즉 받은 인자를 go 함수를 실행하면서 인자를 주고 그 뒤에 함수들을 주면 pipe함수가 만들어진다. 그래서 아래와 같이 나타내어 줄 수 있고 pipe함수는 go함수와 다르게 조금 더 기능을 추가해본다.

 

예를 들어 add함수가 있다고 하면 시작할 때 go함수의 경우는 시작하는 인자가 두개여야 할 때는 add(0, 1)로 작성해고 인자 두개를 1로 평가해서 1로 만들 수 있다.

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

 pipe함수의 경우에는 log(f(0))부분에 add를 해서 전달을 해야한다. 그래서 pipe함수는 인자를 두개를 받는 함수도 사용할 수 있도록 첫번째 함수의 경우는 실행할 때 인자를 두개 이상 전달할 수 있도록 구성되어 있으면 좋다.

log(f(add(0, 1)));

 

즉 아래와 같이 했을 때는 NaN이 나오게 된다. 

<script>
    const go = (...args) => reduce((a, f) => f(a), args);
    const pipe = (...fs) => (a) => go(a, ...fs);

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

    const f = pipe(
        (a, b) => a + b,
        a => a + 10,
        a => a + 100);

    log(f(0, 1));
</script>

동일한 결과가 나오도록 만들어보자. f가 받을 인자가 a인데 ...을 이용해서 여러개의 인자를 받고 첫번째 함수만 꺼내고 나머지함수들을 넣는다.(const pipe = (f, ...fs)) 이런식으로 하면 go코드와 동일한 표현이 된다.

<script>
    const go = (...args) => reduce((a, f) => f(a), args);
    const pipe = (f, ...fs) => (...as) => go(f(...as), ...fs);

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

    const f = pipe(
        (a, b) => a + b,
        a => a + 10,
        a => a + 100);

    log(f(0, 1));
</script>

 

 

 

<출처 : 유인동 함수형 프로그래밍과 JavaScript ES6+>

https://www.inflearn.com/course/functional-es6/dashboard

 

함수형 프로그래밍과 JavaScript ES6+ - 인프런 | 강의

ES6+와 함수형 프로그래밍을 배울 수 있는 강의입니다. 이 강좌에서는 ES6+의 이터러블/이터레이터/제너레이터 프로토콜을 상세히 다루고 응용합니다. 이터러블을 기반으로한 함수형 프로그래밍,

www.inflearn.com