UNPKG

@jsoldi/hkt

Version:

Higher kinded types for typescript and a few utility monads.

55 lines 1.91 kB
import { functor } from "./functor.js"; import { monadTrans } from "./transformer.js"; import { id } from "../core/utils.js"; import { pipe as _pipe } from "../core/utils.js"; const is_monad = Symbol("is_monad"); function _monad(base) { if (is_monad in base) return base; return _pipe(base, base => ({ ...functor({ map: (fa, f) => base.bind(fa, a => base.unit(f(a))), ...base }), ...base }), base => { const lift2 = (f) => (fa, fb) => base.bind(fa, a => base.bind(fb, b => base.unit(f(a, b)))); const lift3 = (f) => (fa, fb, fc) => base.bind(fa, a => base.bind(fb, b => base.bind(fc, c => base.unit(f(a, b, c))))); const flatMap = (f) => (fa) => base.bind(fa, f); const flat = (ffa) => base.bind(ffa, id); const _kleisli = (...fs) => fs.reduceRight((acc, f) => (...arg) => base.bind(f(...arg), a => acc(...[a, ...arg])), base.unit); const _pipe = (head, ...tail) => base.bind(head, _kleisli(...tail)); const _chain = (...fs) => flatMap(_kleisli(...fs)); const runFree = (t) => { if (t.right) { return base.bind(t.value, runFree); } else { return base.unit(t.value); } }; return { [is_monad]: true, lift2, lift3, flatMap, flat, fish: _kleisli, chain: _chain, pipe: _pipe, runFree, ...base }; }); } _monad.trivial = { ..._monad({ unit: a => a, bind: (fa, f) => f(fa), map: (fa, f) => f(fa), }), transform: (inner) => monadTrans({ ...inner, lift: id, wrap: inner.unit }) }; /** The monad factory, providing a set of functions for working with monads. */ export const monad = _monad; //# sourceMappingURL=monad.js.map