모나드 입문
모나드 = 복잡한 처리를 숨기면서 연속된 연산을 가능하게 하는 패턴
- 타입 래퍼 - 값을 감싸는 구조 (예:
NumberWithLogs) - 래핑 함수 (unit/return) - 값을 모나드로 감쌈
- 바인딩 함수 (bind/flatMap) - 래핑된 값에 함수 적용
interface NumberWithLogs {
result: number
logs: string[]
}
function wrapWithLogs(n: number): NumberWithLogs {
return { result: n, logs: [] }
}
function runWithLogs(
input: NumberWithLogs,
transform: (n: number) => NumberWithLogs
): NumberWithLogs {
const next = transform(input.result)
return { result: next.result, logs: [...input.logs, ...next.logs] }
}
Option, Promise도 모나드. then이 바인딩 함수 역할.
단 Promise 는 근사다 — thenable 을 자동으로 펼쳐서 left identity(unit(x).bind(f) === f(x))가 깨진다.1
const v = { then: (r) => r(42) }
const f = (x) => Promise.resolve([x])
f(v) // → [v]
Promise.resolve(v).then(f) // → [42]
Footnotes
-
Promise.resolve() - JavaScript | MDN: “This function flattens nested layers of promise-like objects (e.g., a promise that fulfills to a promise that fulfills to something) into a single layer — a promise that fulfills to a non-thenable value.” ↩