| Apologies in advance for the unsolicited monad tutorial (it's my turn to be that asshole)... Firstly, saying "`X` is a monad" is the same as saying "class `X` implements the monad interface". The monad interface is usually defined with `return` and `bind`, but I think it's more instructive to borrow the terminology from JavaScript's `Promise`... * `Promise#resolve(value)` is the same as `return`, also known as `pure`. It just wraps the given value in a promise. * `Promise#then(function)` combines both `bind` (when a new Promise is constructed and returned) and the functor method `map` (when a plain value is returned). To provide a unified monad/functor interface for both `Promise` and `Array` (using `wrap` instead of `resolve): // `then` provides both `bind` and `map` depending on the return type of the given function:
Promise.prototype.map = Promise.prototype.then
Promise.wrap = Promise.resolve
// f maps elements to arrays of elements:
Array.prototype.then = function (f) {
return [].concat.apply ([], this.map(f))
}
Array.wrap = function (x) {
return [x]
}
There's no intrinsic value beyond that shared interface, it just allows you to write abstractions without knowing specifically what kind of monad you're dealing with (like the "do" syntax).EDIT: BTW, I've purposely skipped a few things in this description, it's meant to be illustrative, not definitive... |