@jsoldi/hkt
Version:
Higher kinded types for typescript and a few utility monads.
46 lines • 1.61 kB
JavaScript
import { monad } from "./monad.js";
import { monoid } from "./monoid.js";
import { pipe } from "../core/utils.js";
import { semiring } from "./semiring.js";
const is_monadPlus = Symbol("is_monadPlus");
/** Creates a `IMonadPlus` from an instance of `IMonadBase` and `IMonoidBase`. */
export function _monadPlus(base) {
if (is_monadPlus in base)
return base;
return pipe(base, base => ({
...monoid(base),
...monad(base),
...base
}), base => {
const guard = (b) => b ? base.unit(null) : base.empty();
const from = (as) => as.reduce((acc, a) => base.append(acc, base.unit(a)), base.empty());
const _semiring = (mult) => semiring({ sum: base, mult: mult.liftMonoid(base) });
const filter = (f) => (fa) => base.bind(fa, a => f(a) ? base.unit(a) : base.empty());
const some = (fa) => base.bind(fa, a => base.map(base.append(some(fa), base.unit([])), as => [a, ...as]));
const many = (fa) => base.append(some(fa), base.unit([]));
return {
[is_monadPlus]: true,
guard,
from,
semiring: _semiring,
filter,
some,
many,
...base,
};
});
}
_monadPlus.const = (t) => _monadPlus({
unit: () => t,
bind: () => t,
map: () => t,
flatMap: () => () => t,
flat: () => t,
empty: () => t,
append: () => t,
});
_monadPlus.void = _monadPlus.const(undefined);
_monadPlus.null = _monadPlus.const(null);
/** The monad plus factory. */
export const monadPlus = _monadPlus;
//# sourceMappingURL=monadPlus.js.map