Skip to content

Instantly share code, notes, and snippets.

@mlms13
Last active May 27, 2020 19:57
Show Gist options
  • Save mlms13/c4774ce7e0bc8c04d283853eec84d3c6 to your computer and use it in GitHub Desktop.
Save mlms13/c4774ce7e0bc8c04d283853eec84d3c6 to your computer and use it in GitHub Desktop.
Promise fails Monad's left identity law
// I've seen some examples of how JS promises fail Functor's composition law
// (by hijacking the `then` field of any JS object), making promises not valid
// functors (and by extension, unlawful monads), but I don't recall seeing a
// concise example of Promise breaking Monad's left identity law (though I'm
// sure this has been demonstrated somewhere before).
//
// The key here is that `return a` doesn't behave as expected when `a` is
// already a promise, due to the auto-collapsing nature of promises.
// Left Identity:
// return a >>= f === f a
// Law, rewritten in JS:
// bind(pure(a), f) === f(a)
let bind = (x, f) => x.then(f);
let pure = Promise.resolve;
let a = Promise.resolve("foo");
let f = x => x.then(y => Promise.resolve(y.length));
// The right side of the law, producing a promise of 3
f(a);
Promise
.resolve("foo")
.then(y => Promise.resolve(y.length));
// The left side of the law (with substitution), producing nonsense
bind(pure(a), f); // the law (left side)
bind(Promise.resolve(a), f); // substitute `pure`
Promise.resolve(a).then(f); // substitute `bind`
Promise.resolve(Promise.resolve("foo")).then(f); // substitute `a`
// substitute `f`
Promise
.resolve(Promise.resolve("foo"))
.then(x => x.then(y => Promise.resolve(y.length)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment