Functor
https://github.com/eu81273/jsfiddle-console
by dimitrs_papadimitriou
HTML
<script src="https://rawgit.com/eu81273/jsfiddle-console/master/console.js"></script>
JavaScript
const Ok = v => ({
map: f => Ok(f(v)),
chain: f => f(v),
cata: alg => alg.Ok(v)
});
const Error = v => ({
map: () => Error(v),
chain: () => Error(v),
cata: alg => alg.Error(v)
});
var Reader = (expr) => ({
ask: () => expr,
map: f => Reader(env => f(expr(env))),
run: env => expr(env),
ap: reader => Reader(env => Reader(expr).run(env)(reader.run(env))),
chain: f => Reader(env => f(expr(env)).run(env)),
});
var safe = f => {
try {
return Ok(f())
} catch (e) {
return Error(e)
}
}
(function () {
const compose = (...fns) => fns.reduceRight((g, f) => x => g(f(x)), x => x);
const composeM = (...fns) => fns.reduceRight((g, f) => x => g(x).chain(f), Ok);
const EitherAsync = (actions, res, rej) => ({
map: (f) => EitherAsync(actions, composeM(x => Ok(x).map(f), res), rej),
mapError: (f) => EitherAsync(actions, res, compose(f, rej)),
chain: f => EitherAsync(actions, composeM(f, res), rej),
app: fv => EitherAsync(actions, composeM(f => fv.map(f), res), rej),
cata: alg => actions(x => res(x).cata(alg), composeM(alg.Error, rej)),
toEither: () => EitherAsync(actions, res, rej),
chainReader: reader => EitherAsync(actions, x => safe(() => (reader.run(x))).chain(res), rej),
});
Promise.prototype.toEither = function () {
return EitherAsync((resolve, reject) => this.then(resolve).catch(reject), Ok, Ok);
}
var toEither = (promise) => {
return EitherAsync((resolve, reject) => promise.then(resolve).catch(reject), Ok, Ok);
}
}())
Array.prototype.traverse = function (TyperRep, f) {
if (this.length === 0) {
return TyperRep([]);
} else {
var head = this.shift();
return TyperRep(x => y => x.concat(y))
.ap(f(head).map(x => [x]))
.ap(this.traverse(TyperRep, f));
...