함수를 합성하는 과정에서 예상치 못한 에러들이 생길 수 있다.
함수 합성 중 에러에 대한 것도 처리해서 모나드를 만드는 것이 kleisli Composition인 것 같다.
좀 더 직관적인 표현으로는 f(g(x)) = g(x)
로 생각해볼 수 있다.
var users = [
{id: 1, name: 'aa'},
{id: 2, name: 'bb'},
{id: 3, name: 'cc'}
];
const getUserById = id =>
find(u => u.id == id, users)
const f = ({name}) => name;
const g = getUserById;
const fg = id => Promise.resolve(id).then(g).then(f);
위의 결과는 g에서 id를 못찾는다면, 함수 fg의 평가는 원하지 않는 값이 나오게 된다.
문제를 해결하기 위해서 JS에서는 Promise.reject()
를 이용하여 실패에 대한 처리를 하게 된다.
그러면 위의 코드는
var users = [
{id: 1, name: 'aa'},
{id: 2, name: 'bb'},
{id: 3, name: 'cc'}
];
const getUserById = id =>
find(u => u.id == id, users) || Promise.reject("없어요!")
const f = ({name}) => name;
const g = getUserById;
const fg = id => Promise.resolve(id).then(g).then(f).catch(log);
g함수가 실패하여 바로 catch
로 빠져서 promise의 형태(monad)가 깨지지 않게 된다.
매우 어렵다. 아직도 갈 길이 멀다.