Skip to content

Instantly share code, notes, and snippets.

@ksoda
Last active May 6, 2020 11:57
Show Gist options
  • Save ksoda/9eb4e22ac889fd05bf38 to your computer and use it in GitHub Desktop.
Save ksoda/9eb4e22ac889fd05bf38 to your computer and use it in GitHub Desktop.
Monad in Javascript
myTrue = (x, y) => x;
myFalse = (x, y) => y;
ifThen = (cond, whenTrue, whenFalse) => cond(whenTrue, whenFalse);
ifThen(myTrue, 1, 2);
ifThen(myFalse, 1, 2);
cons = (elm, rest) => (c) => c(elm, rest);
head = (lst) => lst(myTrue);
tail = (lst) => lst(myFalse);
mempty = (f) => myTrue;
head(tail(cons(1, cons(2, mempty))));
class Just {
constructor(value) {
this.value = value;
}
bind(transform) {
return transform(this.value);
}
toString() {
return ["Just(", this.value, ")"].join("");
}
}
class Nothing {
bind() {
return this;
}
toString() {
return "Nothing";
}
}
function pure(value) {
return new Just(value);
}
// Usage
class Pole {
constructor(left, right) {
this.leftBirds = left;
this.rightBirds = right;
}
landLeft(birds) {
const left = this.leftBirds + birds,
right = this.rightBirds;
return this.constructor.isSafe(left, right)
? new Just(new Pole(left, right))
: new Nothing();
}
landRight(birds) {
const left = this.leftBirds,
right = this.rightBirds + birds;
return this.constructor.isSafe(left, right)
? new Just(new Pole(left, right))
: new Nothing();
}
static isSafe(left, right) {
return Math.abs(left - right) < 4;
}
toString() {
return ["(", this.leftBirds, ", ", this.rightBirds, ")"].join("");
}
}
// Usage Maybe
function main() {
console.log(
"" + new Just(1).bind((x) => new Just(2).bind((y) => new Just(x + y))),
"" + new Just(1).bind((x) => new Nothing(2).bind((y) => new Just(x + y)))
);
const result = pure(new Pole(0, 0)).bind((p1) =>
p1.landRight(3).bind((p2) => p2.landLeft(6).bind((p3) => p3.landRight(-3)))
);
console.log("" + result);
}
main();
@ksoda
Copy link
Author

ksoda commented Aug 16, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment