함수 합성 시, 함수에 어떤 값이 들어올지 모르는 상황에서의 함수 합성을 어떻게 하면 안전하게 할 수 있을까?
const g = a => a + 1;
const f = a => a * a;
console.log(f(g(1))); // 4
console.log(f(g())); // NaN
위와 같은 경우가 문제가 된다. 숫자가 들어갈 경우에는 제대로 함수 합성이 되겠지만, 값이 들어가지 않을 경우에는 NaN이 반환된다. 이를 해결하기 위한 모나드는 예컨대 아래와 같다.
[1].map(g).map(f).forEach(r => console.log(r)); // 4
[].map(g).map(f).forEach(r => console.log(r)); //
배열이라는 박스를 만들어 map 함수를 통해 배열 내부의 요소에 g 함수와 f 함수를 적용한다. 그리고 forEach 함수로 배열 내부의 요소를 순환하며 반환하는 것이다. 이 경우 Array에 요소가 없다면 forEach에서 내보낼 요소도 없어지므로 아무것도 반환하지 않게 된다. 이러한 모나드 관점에서 Promise를 바라보면 어떨까?
Promise.resolve(1).then(g).then(f).then(r => console.log(r)); // 4
Promise.resolve().then(g).then(f).then(r => console.log(r)); // NaN
Promise의 then으로 함수 합성을 시도하면 값이 없을 경우 NaN을 반환한다. 모나드가 아니네? 라고 생각할 수도 있겠지만, Promise는 조금 다른 관점에서의 모나드라 할 수도 있다. Promise는 값이 들어있고 들어있지 않고에서의 안전성을 보장하는 것이 아닌, 비동기 상황에서, 즉 딜레이가 발생할 수 있는 값이 들어왔을 때 함수 합성의 안전을 보장해주기 때문이다. 즉 이러한 관점에서 Promise는 비동기시 함수 합성을 보장해주는 모나드라 할 수 있다.
'WEB > JS' 카테고리의 다른 글
[JS] forEach, for in, for of의 차이 (1) | 2019.05.05 |
---|---|
[JS] 코드를 값으로 다루는 go, pipe, curry 함수 만들기 (0) | 2019.05.03 |
[JS] 이터러블 프로토콜을 따르는 map, filter, reduce 함수 만들기 (0) | 2019.04.29 |
[JS] 콜스택과 이벤트루프 (0) | 2019.02.22 |
[JS] 커링(Currying) (0) | 2019.02.19 |