본문으로 바로가기

자바스크립트에서의 모나드

category WEB/JS 2019. 5. 18. 15:02

함수 합성 시, 함수에 어떤 값이 들어올지 모르는 상황에서의 함수 합성을 어떻게 하면 안전하게 할 수 있을까?

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는 비동기시 함수 합성을 보장해주는 모나드라 할 수 있다.

 

함수형 프로그래밍과 ES6+ / 유인동님