본문 바로가기
JavaScript

[FP&ES6+] go, pipe, curry - (1)

by _sweep 2021. 12. 10.

함수형 프로그래밍과 JavaScript ES6+ 강의를 듣고 정리한 내용입니다.

 

 

*** 코드를 값으로 다루기 => 평가하는 시점을 원하는 대로 다룰 수 있다.

 

 

go

 

const go = (...args) => reduce((a, f) => f(a), args)

 

인자들을 받아 하나의 값으로 축약해 나가는 함수이다.

 

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

// output
// 111

 

위와 같이 쓰게 된다면 args는 순서대로 0, f, f, f, f가 들어간다.

따라서 0이 a => a + 1의 인자로 들어가 1이라는 값이 되고 이 값이 a => a + 10의 인자로 들어가 11이라는 값이 되고

또 이 값이 a => a + 100의 인자로 들어가 111이라는 값이 되어 제일 마지막 args인 console.log에 의해 출력된다.

 

초기값을 따로 주지 않고 함수만 전달할 때도 다음과 같이 사용할 수 있다.

 

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

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

// output
// 111

 

위와 같은 상황에서도 함수의 결과값이 순서대로 전해져 내려온다.

 

 

 

pipe

 

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

 

함수를 리턴하는 함수이다. 합성된 함수를 만든다.

 

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

console.log(f(0))

// output
// 111

 

위의 go의 예제와 동작하는 것은 동일하다.

다만 값을 계산하는 부분을 담당하는 함수를 따로 빼 합성한 것과 같은 모양새이다.

 

 

만약 pipe를 이용한 합성된 함수에 인자를 2개 이상 전달하고 싶을 때는 다음과 같다.

 

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

 

제일 처음에 선언된 함수 하나와 나머지 함수들이 주어진다.

합성 함수의 인자들로 제일 먼저 선언된 함수를 계산한 후 계산되어 하나로 합쳐진 값들이 나머지 함수의 인자 값으로 넘어가게 된다.

 

이에 대한 예시를 보자면 다음과 같다.

 

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

console.log(f2(0, 1))

// output
// 111

 

f2는 pipe로 묶인 합성 함수이다.

이때 f2에 0과 1이라는 인자값이 들어간다.

이 0과 1은 제일 처음 선언된 함수인 (a, b) => a + b에 들어가고 0 + 1의 결과인 1을 반환한다.

이 1이 다음 함수인 a => a + 10에 들어가고 이 결과값이 또 a => a + 100의 인자로 들어가게 되면서 111이라는 값이 반환된다.

그리고 이 값을 console.log()로 출력하는 것이다.

 

 

 

✏️ 예제

 

const fruits = [
    { name: '사과', price: 1000 },
    { name: '바나나', price: 2000 },
    { name: '딸기', price: 1500 },
    { name: '레몬', price: 1000 },
    { name: '복숭아', price: 3000 }
];

 

이러한 값이 주어졌다고 했을 때 값이 2000원 미만인 과일들의 가격 총 합을 구한다고 해보자.

이전에는 map, reduce, filter를 이용해 다음과 같은 코드를 짤 수 있었다.

 

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

console.log(
    reduce(
        add,
        map(f => f.price,
            filter(f => f.price < 2000, fruits)
        )
    )
)

// output
// 3500

 

그러나 go 함수를 사용해 이를 더 보기 쉽게 표현할 수 있게 되었다.

 

go(
    fruits,
    fruits => filter(f => f.price < 2000, fruits),
    fruits => map(f => f.price, fruits),
    prices => reduce(add, prices),
    console.log
)

// output
// 3500

 

먼저 fruits가 주어지면 filter를 이용해 fruits 중 가격이 2000 미만인 과일들을 골라내고 map을 이용해 그들의 가격을 뽑아낸 뒤 reduce를 이용해 총합을 구한다.

그리고 console.log로 출력한다.

 

 

 

 

 

'JavaScript' 카테고리의 다른 글

[FP&ES6+] go, pipe, curry - (3)  (0) 2021.12.11
[FP&ES6+] go, pipe, curry - (2)  (0) 2021.12.10
[FP&ES6+] map, filter, reduce  (0) 2021.12.01
[FP&ES6+] 제너레이터  (0) 2021.12.01
[FP&ES6+] 리스트 순회와 이터러블, 이터레이터  (0) 2021.10.29

댓글