UNPKG

@jsoldi/hkt

Version:

Higher kinded types for typescript and a few utility monads.

51 lines 1.76 kB
import { fold } from "./fold.js"; import { monad } from "./monad.js"; import { chain, pipe } from "../core/utils.js"; const is_foldable = Symbol("is_foldable"); /** Creates an `IFoldable` from an `IFoldableBase`. */ export function foldable(base) { if (is_foldable in base) return base; return pipe(base, base => ({ ...fold({ scalar: monad.trivial, ...base, }), scalar: monad.trivial, ...base }), base => { /** Passed monad must transform from $<M, T> to $<G, $<M, T>> given G */ const liftFoldOver = (m) => { const _m = monad(m); return fold({ map: (fma, f) => base.map(fma, _m.fmap(f)), scalar: _m, //: m.transform(base.scalar), foldl: f => b => base.foldl(_m.lift2(f))(_m.unit(b)), }); }; /** Passed monad must transform from $<M, T> to $<M, $<G, T>> given G */ const liftFoldUnder = (m) => { const _m = monad(m); return fold({ map: (fa, f) => _m.map(fa, base.fmap(f)), scalar: _m, //: m.transform(base.scalar), foldl: f => b => _m.fmap(base.foldl(f)(b)) }); }; const nestFold = (m) => { return fold({ map: (fa, f) => base.map(fa, ma => m.map(ma, f)), foldl: f => chain(m.scalar.unit, base.foldl((nb, ma) => m.scalar.bind(nb, b2 => m.foldl(f)(b2)(ma)))), scalar: m.scalar }); }; return { [is_foldable]: true, nestFold, liftFoldOver, liftFoldUnder, ...base }; }); } //# sourceMappingURL=foldable.js.map