@jsoldi/hkt
Version:
Higher kinded types for typescript and a few utility monads.
90 lines • 3.23 kB
JavaScript
import { monadPlus } from "../classes/monadPlus.js";
import { monadTrans } from "../classes/transformer.js";
import { traversable } from "../classes/traversable.js";
import { foldable } from "../classes/foldable.js";
import { either } from "./either.js";
import { monoid } from "../classes/monoid.js";
/** The maybe module, providing a set of functions for working with `Maybe` values. */
export const maybe = (() => {
const base = either.of();
const just = (a) => base.right(a);
const nothing = base.left(undefined);
const isJust = (fa) => fa.right;
const isNothing = (fa) => !fa.right;
const fromList = (fa) => fa.length > 0 ? just(fa[0]) : nothing;
const toList = (fa) => fa.right ? [fa.value] : [];
const map = (fa, f) => fa.right ? just(f(fa.value)) : nothing;
const unit = (a) => just(a);
const bind = (fa, f) => fa.right ? f(fa.value) : nothing;
const fromNullable = (a) => a == null ? nothing : just(a);
const empty = () => nothing;
const append = base.append;
const _if = (cond) => cond ? just(null) : nothing;
const _monadPlus = monadPlus({
map,
unit,
bind,
empty,
append
});
const _foldable = foldable({
map,
foldl: f => b => fa => fa.right ? f(b, fa.value) : b
});
const transform = (m) => {
const et = base.transform(m);
const __monadTrans = monadTrans({
map: et.map,
unit: et.unit,
bind: et.bind,
lift: et.lift,
wrap: et.wrap
});
const __monoid = monoid({
empty: () => m.unit(empty()),
append: (fa, fb) => m.bind(fa, ma => ma.right ? m.unit(ma) : fb)
});
const __foldable = _foldable.liftFoldUnder(m);
return {
...__monadTrans,
...__foldable,
...monadPlus({
append: __monoid.append,
bind: __monadTrans.bind,
empty: __monoid.empty,
unit: __monadTrans.unit,
}),
or: (b) => (fa) => m.bind(fa, ma => (ma.right ? m.unit(ma) : b)),
and: (b) => (fa) => m.bind(fa, ma => (ma.right ? b : m.unit(ma))),
else: (b) => (fa) => m.bind(fa, ma => (ma.right ? m.unit(ma.value) : b())),
either: (onLeft, onRight) => (fa) => m.bind(fa, ma => (ma.right ? onRight(ma.value) : onLeft())),
fromList: (fa) => m.map(fa, fromList),
toList: (fa) => m.map(fa, toList),
fromNullable: (a) => m.map(a, fromNullable),
if: (cond) => m.map(cond, _if)
};
};
const _traversable = traversable({
traverse: m => f => fa => fa.right ? m.map(f(fa.value), unit) : m.unit(empty())
});
return {
..._traversable,
..._foldable,
..._monadPlus,
if: _if,
just,
nothing,
isJust,
isNothing,
fromList,
toList,
fromNullable,
or: base.or,
and: base.and,
else: base.else,
either: base.either,
transform,
liftMonoid: transform, // Override default to make it short-circuit on append
};
})();
//# sourceMappingURL=maybe.js.map