4.5 Extending Promise to Functor
https://github.com/eu81273/jsfiddle-console
by dimitrs_papadimitriou
HTML
<script src="https://rawgit.com/eu81273/jsfiddle-console/master/console.js"></script>
JavaScript
class Either {
map(f) {
throw new Error('You have to implement the method map!');
}
matchWith(pattern) {
throw new Error('You have to implement the method matchWith!');
}
bind(f) {
return this.matchWith({
left: (e) => new Left(e),
right: (v) => f(v)
})
}
}
class Right extends Either {
constructor(value) {
super();
this.value = value;
}
map(f) {
return new Right(f(this.value))
}
matchWith(pattern) {
return pattern.right(this.value)
}
}
class Left extends Either {
constructor(value) {
super();
this.value = value;
}
map(f) {
return new Left(this.value);
}
matchWith(pattern) {
return pattern.left(this.value)
}
}
(function () {
const compose = (...fns) => x => fns.reduceRight((y, f) => f(y), x);
const id = x => x;
const EitherAsync = (actions, resolveMappings, rejectMappings) => ({
map: (f) => EitherAsync(actions, compose(f, resolveMappings), rejectMappings),
bind: f => EitherAsync((resolve, reject) => actions(x => f(resolveMappings(x)).matchWith({
right: resolve,
left: reject
}), reject), id, id),
matchWith: alg => actions(compose(alg.right, resolveMappings), compose(alg.left, rejectMappings)),
toPromise: () => new Promise((resolve, reject) => actions(compose(resolve, resolveMappings), compose(reject, rejectMappings))),
toEither: () => EitherAsync(actions, resolveMappings, rejectMappings),
});
Promise.prototype.toEither = function () {
return EitherAsync((resolve, reject) => this.then(resolve).catch(reject), id, id);
}
}())
Promise.prototype.matchWith = function (pattern) {
return this.then(pattern.right).catch(pattern.left)
}
Promise.prototype.bind = function (f) {
return this.then(f)
}
Promise.prototype.map = function (f) {
return this.then(f)
}
var...