Either monad bind
https://github.com/eu81273/jsfiddle-console
by dimitrs_papadimitriou
HTML
<script src="https://rawgit.com/eu81273/jsfiddle-console/master/console.js"></script>
JavaScript
class Maybe {
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) {
throw new Error('You have to implement the method bind!');
}
}
class Some extends Maybe {
constructor(value) {
super();
this.value = value;
}
map(f) {
return new Some(f(this.value))
}
matchWith(pattern) {
return pattern.some(this.value)
}
bind(f) {
return f(this.value)
}
}
class None extends Maybe {
map(f) {
return new None();
}
matchWith(pattern) {
return pattern.none()
}
bind(f) {
return new None()
}
}
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)
}
}
Array.prototype.matchWith = function (pattern) {
return this.length === 0 ? pattern.empty() : pattern.concat(this.shift(), this);
};
Array.prototype.firstOrNone = function (predicate) {
return this.matchWith({
empty: () => new None(),
concat: (value, rest) => predicate(value) ?
new Some(value) :
rest.firstOrNone(predicate)
})
}
Maybe.prototype.ToEither = function (defaultLeft) {
return...