이전 강의 내용
const queryStr = pipe(
Object.entries,
map(([k, v]) => `${k}=${v}`),
reduce((a, b) => `${a}&${b}`)
);
reduce를 보면 Array에 있는 join 함수와 같은 결과물을 반환한다. 그런데 Array의 join 메서드는 Array prototype에만 붙어있는 메서드다.
이때, reduce는 이터러블 객체를 순회하면서 값을 join하기에 조금 더 다형성이 높은 함수라고 볼 수 있다.
Join 함수
const join = curry((sep = ',', iter) =>
reduce((a, b) => `${a}${sep}${b}`, iter));
const queryStr = pipe(
Object.entries,
map(([k, v]) => `${k}=${v}`),
join('&')
);
console.log(queryStr({ limit: 10, offset: 10, type: 'notice' }));
join 함수는 separator와 iterable한 값을 받아서 reduce를 통해 iterable한 값을 순회하면서 중간에 separator를 넣는 함수다.
커스텀으로 생성한 join은 Array가 아니더라도 사용할 수 있어 다형성이 높다.
함수형 프로그래밍을 하면 파이프 사이사이에 있는 함수들을 조합하여 재사용성이 높게 활용할 수 있다.
예를 들어, well formed iterator를 반환하는 제너레이터를 순회한다고 했을 때,
function *a() {
yield 10;
yield 11;
yield 12;
yield 13;
}
console.log(join(' - ', a()));
// 10 - 11 - 12 - 13
아래와 같이 사용할 수 있어서 다형성이 높기에 자연스레 조합성 또한 높아진다. 이때, 이터러블 프로토콜을 따르고 있기 때문에 지연 평가를 할 수 있다는 것을 알 수 있다. reduce에서 next()를 통해 값을 하나씩 순회하기 때문이다.
이제 지연평가를 적용하여 함수 식을 바꿔보자
L.entries = function *(obj) {
for (const k in obj) yield [k, obj[k]];
};
const join = curry((sep = ',', iter) =>
reduce((a, b) => `${a}${sep}${b}`, iter));
const queryStr = pipe(
L.entries,
L.map(([k, v]) => `${k}=${v}`),
join('&')
);
console.log(queryStr({ limit: 10, offset: 10, type: 'notice' }));
지연 평가를 하고 있는지, L.entries와 L.map 사이에 console.log를 넣어보면 아래와 같은 값을 출력한다.
L.entries {<suspended>}
정상적으로 평가를 미루고 있음을 확인할 수 있다.
다형성이 높은 함수는 그 자체로 의미가 있는 함수이지만, 다형성이 높은 것을 활용해서 다양한 함수와 조합하여 사용할 수 있도록 함수를 조합 및 체이닝 할 수 있다는 점에서 굉장히 유용한 성질이라고 생각한다. 그리고, 이터러블 프로토콜을 따르는 것은 곧 지연 평가를 할 수 있다는 의미이며, 지연 평가를 할 수 있다는 것은 제때 원하는 때에만 평가를 실행할 수 있기 때문에 더 효율적으로 코드를 동작하게 할 수 있다는 것과 같다. 앞선 사례들을 적절히 혼합하여 성능 최적화를 해보면 좋을 것 같다.
출처: 인프런 함수형 프로그래밍과 JavaScript ES6+
'프론트엔드 > JS' 카테고리의 다른 글
[JavaScript] L.map, L.filter로 map과 filter 만들기 (0) | 2023.05.09 |
---|---|
[JavaScript] 함수 합성을 통해 find 함수 만들기 (0) | 2023.05.08 |
[JavaScript] map, filter & reduce로 결과를 만드는 함수 생성 (0) | 2023.05.07 |
[JavaScript] map, filter 계열 함수들이 가지는 결합 법칙, 지연평가의 장점 (0) | 2023.05.05 |
[JavaScript] L.range, L.map, L.filter, take의 평가 순서 및 효율성 (0) | 2023.05.03 |