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...