Functors Compose, Monads Do Not

Posted on March 25, 2019 by Riccardo

Functor Composition

Let’s start with a refresher of map:

In other words, map takes a function a -> b and gives us a function f a -> f b. For that reason, we can take any two nested functors (e.g. Array and Maybe) and run a function on the nested values by putting two maps together:

Monad Composition

This time we want to take a look at bind:

If we tried to compose the same way we did with functors, we would notice the code does not compile:

The problem here is in the nested bind:

In fact, Maybe Int -> (Int -> Array (Maybe String)) -> ?? is not what bind expects: the first argument seems to indicate that m is Maybe but the second seems to indicate that m is Array. This does not compile since the monad m is supposed to be the same.

To make the program compile we have to make use of a function (i.e. maybe) specific to the monad we are dealing with (i.e. Maybe):

Or we could use the MaybeT monad transformer:


I’ve blatantly copied the content of this blog post out of a talk by Tony Morris. So be sure to check the original stuff out!

If you liked the post and want to help spread the word, please make some noise 🤘 But only if you really liked it. Otherwise, please feel free to comment or tweet me with any suggestions or feedback. And please do cause I need help with my FP!