Monads
Our last abstraction will solve the very problem we raised in the previous section: how to safely perform intermediate calculations by preserving the semantics of the abstractions we're working with—in this case, options.
It should be no surprise now that fluokitten also provides a protocol for Monads, simplified and shown as follows:
(defprotocol Monad (bind [mv g]))
If you think in terms of a class hierarchy, Monads would be at the bottom of it, inheriting from Applicative Functors, which, in turn, inherit from Functors. That is, if you're working with a Monad, you can assume it is also an Applicative and a Functor.
The bind
function of monads takes a function g
as its second argument. This function receives as input the value contained in mv
and returns another Monad containing its result. This is a crucial part of the contract: g
has to return a Monad.
The reason why will become clearer after some examples. But first, let's promote our Option abstraction to...