Advice for combining multiple monads

Let us first discuss why we are using monads and how they let us develop better programs. In my opinion, the core idea of a monad is that it is an abstraction that enables us to write generic code. Generic code, in turn, reduces coupling and improves code reuse, improving the code quality, by making it easier to read1, maintain, and change. How a monad structure is implemented is an implementation detail, which should be hidden to reduce the monad user’s cognitive load and prevent the abstraction’s leaking.

Your simple example demonstrates that having several monads in the scope of the same expression greatly increases the cognitive load as you have to operate with all of them at once. Instead, I suggest defining a single monad, which would be domain-specific, i.e., a construction that is relevant to your application. You can add extra layers of different monads to it, but hide the actual implementation under the interface. You can extend the interface with helper functions and let-binding operators for common cases, like let? that will operate on optional types, or let?! which will handle or_errors, and so on. But you shall never mix monads in the user code. The user code shall see only one monad.

To summarize, shake well your monads before usage and use a straw.


1) As a powerful abstraction, monads reduce cognitive load. However, the germane load is very high, – monadic code is generally perceived as incomprehensible by programmers that are not well-versed in monads, which is, probably, the majority of programmers.

8 Likes