4.6.6 Promises and the Either Monad
by dimitrs_papadimitriou
HTML
<script src="https://rawgit.com/eu81273/jsfiddle-console/master/console.js"></script>
JavaScript
var safe = fn => {
try {
return new Right(fn())
}
catch (e) { return new Left(e) }
}
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)
})
}
safeMap(f) {
return this.matchWith({
left: (e) => new Left(e),
right: (v) => safe(() => f(v))
})
}
safeBind(f) {
return this.matchWith({
left: (e) => new Left(e),
right: (v) => safe(() => f(v))
.matchWith({
left: (e) => new Left(e),
right: (v) => 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)
}
}
new Right(5)
.map(x => x + 1)
.safeMap(x => { throw x })
.matchWith({
right: (v) => console.log("the result: " + v),
left: (error) => console.log("error during execution " + error)
})
Promise.resolve(5)
.then(x => x + 1)
.then(x => { throw x })
.then((v) => console.log("the result: " + v))
.catch((error) => console.log("error during execution " + error))