# Making your brain tingle: Explaining Monads

# My attempt at explaining monads

It is an unwritten law, that everybody learning Haskell sooner or
later has to write a tutorial or explanation of the topic of
monads. (The fourth monad law.)^{1}

So here is my attempt at explaining monads, I will try to give an intuition on what monads are from the practical view of a developer. I’m going to use examples in Haskell, so yes, this time I’m going to assume, some basic knowledge of Haskell – but a seasoned developer might still be able to figure out the essence of the examples without learning Haskell.

## Monads are functors…

First and foremost, monads are functors. And so the metaphor of containers works for them as well, at least as a first approximation. But what makes a functor a monad?

To make this intuitive lets start with an example of a simple task:
Lets say we have a list of integers, and we want to extend the list by
inserting the result of the multiplication with two, after each of
them. So given a list `[1,2,3]`

we want to get the list
`[1,2,2,4,3,6]`

.

As written in my last
article for each functor
there is a way to map functions, so that, staying in the picture of
containers, they operate on the content of the container. In Haskell
the function `fmap`

does this mapping. Lists are functors, so lets
try to solve the task using `fmap`

:

```
addTimesTwo :: Int -> [Int]
addTimesTwo x = [x, x*2]
-- and fmap it into our functor:
fmap addTimesTwo [1..3]
-- returns: [[1,2],[2,4],[3,6]]
```

Ooops, that’s not what we wanted to do. I could now try this or that,
but – spoiler ahead – there is absolutely no way this could be done
using just `fmap`

. The reason is that an `fmap`

-ed function by
definition can only operate on the content of our containers, but our
task includes the requirement to enhance the list, which would mean to
change the container itself.

In terms of types: having a list `[Int]`

and a function ```
Int ->
[Int]
```

, when mapping the function to the list we will get a result of
the type `[[Int]]`

, but we wanted a `[Int]`

. Or more general: having
a functor `F a`

and a function `a -> F a`

mapping will give us ```
F (F
a)
```

.

Of course, the task at hand can still be solved relatively easily, we just have to operate on the list (our functor) directly:

```
addTimesTwoInList :: [Int] -> [Int]
addTimesTwoInList [] = []
addTimesTwoInList (x:xs) = x : x*2 : addTimesTwoInList xs
addTimesTwoInList [1..3]
-- returns: [1,2,2,4,3,6]
```

That wasn’t to hard, was it? But we lost a lot of abstraction. Let’s say we need another function, doing the same thing, but with a different math operation, for example adding 42 instead of multiplication with two? We can write this function, too:

```
addPlusFortytwoInList :: [Int] -> [Int]
addPlusFortytwoInList [] = []
addPlusFortytwoInList (x:xs) = x : x+42 : addPlusFortytwoInList xs
addPlusFortytwoInList [1..3]
-- returns: [1,43,2,44,3,45]
```

That’s a lot of duplicated logic. Let’s see if we can factor out the
list manipulation in a way, so that we can use our original function
`addTimesTwo`

:

```
applyToList :: (a -> [b]) -> [a] -> [b]
applyToList _ [] = []
applyToList f (x:xs) = f x ++ applyToList f xs
addTimesTwo :: Int -> [Int]
addTimesTwo x = [x, x*2]
addPlusFortytwo :: Int -> [Int]
addPlusFortytwo x = [x, x+42]
-- Try it:
applyToList addTimesTwo [1..3]
-- returns: [1,2,2,4,3,6]
applyToList addPlusFortytwo [1..3]
--returns: [1,43,2,44,3,45]
```

That’s much better! So what have we done here? Well, we wrote a special function for function application to a list.

## …with specific rules for joining in function application

While the type of standard function application is:
`(a -> b) -> a -> b`

we created a new variation with the type
`(a -> [b]) -> [a] -> [b]`

,
that’s quite the similarity! The difference is the asymmetry in the
argument type of the function we apply and the type of argument we
provide: we only give the contents of our container (the list) to the
function, which returns a new container of the same functor type
(list)^{2}, then it is the task of our new function application
method, to join the two containers: the one of the argument (which it
kind of kept back from the called function) and the one of the result.

As we invented a way to apply functions, we can now of define function combination as well:

```
after :: (b -> [c]) -> (a -> [b]) -> (a -> [c])
after g f = applyToList g . f
-- and test it:
applyToList addPlusFortytwo (applyToList addTimesTwo [1..3])
-- returns: [1,43,2,44,2,44,4,46,3,45,6,48]
applyToList (addPlusFortytwo `after` addTimesTwo) [1..3]
-- returns: [1,43,2,44,2,44,4,46,3,45,6,48]
```

Ok, so that’s nice, now we have function combination for functors.
But we have only defined our clever new function application for
lists. The concept of automatically joining containers during
function application is generic, so lets implement it for another
functor. The canonical second example is `Maybe`

:

```
applyToMaybe :: (a -> Maybe b) -> Maybe a -> Maybe b
applyToMaybe _ Nothing = Nothing
applyToMaybe f (Just x) = f x
after2 :: (b -> Maybe c) -> (a -> Maybe b) -> (a -> Maybe c)
after2 g f = applyToMaybe g . f
```

```
-- and some functions, to test it:
import Data.Char (toLower)
import Data.List (elemIndex)
firstChar :: String -> Maybe Char
firstChar "" = Nothing
firstChar (c:_) = Just c
positionInAlphabet :: Char -> Maybe Int
positionInAlphabet c = (+1) <$> elemIndex (toLower c)
"abcdefghijklmnopqrstuvwxyz"
-- put it to the test:
applyToMaybe (positionInAlphabet `after2` firstChar) (Just "")
-- returns: Nothing
applyToMaybe (positionInAlphabet `after2` firstChar) (Just "Foo")
-- returns: Just 6
applyToMaybe (positionInAlphabet `after2` firstChar) (Just ":-)")
-- returns: Nothing
```

Ok, function application and combination with automatic handling of
the functor joining works in this case, too. The only ugliness left
is that we are inventing a new name for the application function (and
therefore for the combination function) per functor. Unfortunately we
can not write one generic `apply`

for all functors, as they are to
diverse in their semantics (just as we can not write one common
version of fmap for all functors). So, we will need a specific
implementation per functor, but we can make it ad-hoc polymorphic
through a type class:

```
class Functor f => FancyFunctor f where
apply :: (a -> f b) -> f a -> f b
after :: (b -> f c) -> (a -> f b) -> (a -> f c)
after g f = apply g . f
instance FancyFunctor [] where
apply _ [] = []
apply f (x:xs) = f x ++ apply f xs
instance FancyFunctor Maybe where
apply _ Nothing = Nothing
apply f (Just x) = f x
```

Now we can write function combination for our different fancy functors in a unified way:

```
apply (addPlusFortytwo `after` addTimesTwo) [1..3]
-- returns: [1,43,2,44,2,44,4,46,3,45,6,48]
apply (positionInAlphabet `after` firstChar) (Just "abc")
-- returns: Just 1
```

Sweet. But what has all that to do with monads? Well, we just
invented them! Our special `apply`

function is called *bind* in terms
of monads in Haskell, and the `after`

operator derived from it is
called *Kleisli composition*. Functors for which these operations are
defined are called *monads*, as is the matching type class in Haskell.

And yes, lists and `Maybe`

are monads in Haskell, so the functions we
just created are already predefined for them.

## Some unnecessary confusion

So what are these functions called in standard haskell monads? Well,
just like the standard function application `$`

and function
combination `.`

they are defined as infix operators in haskell: the
commonly used bind operator is `>>=`

and the matching Kleisli
composition is written as `>=>`

. But a quick glance at the types of
the monad functions shows that the arguments are flipped compared to
our versions:

```
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
```

So we have to write:

```
import Control.Monad
(Just "Example") >>= (firstChar >=> positionInAlphabet)
-- returns: Just 5
(Just ")-:") >>= (firstChar >=> positionInAlphabet)
-- returns: Nothing
```

I think, this is a pity as it obfuscates the similarity
between the function application operator `$`

and the monadic bind.
But that is only with the commonly used
bind operator. There are versions of both operators with flipped
arguments:

```
(positionInAlphabet <=< firstChar) =<< (Just "Hurray")
-- returns: Just 8
(addPlusFortytwo <=< addTimesTwo) =<< [1..3]
-- returns: [1,43,2,44,2,44,4,46,3,45,6,48]
```

These, in my opinion more consistent versions, are not commonly
used, but at least they exist. It is worth mentioning though,
that `>>=`

is in prelude, while `=<<`

is only in Control.Monad.

## Give me my monad

There is one more function which must be defined for every monad and
which I didn’t mention yet. It is `return`

and its type is ```
Monad m
=> a -> m a
```

. So for any value, `return`

gives you the value mapped to
a monadic functor. So this is basically a generic version of a type
constructor for monads. There are at least two reasons why this is
needed:^{3}

It allows us to write polymorphic functions which can operate on any monad.

It allows the creator of a monad, to do fancy stuff on the creation of a monadic value.

# An example of state

Now that we have a first impression what monads are, and why they are useful. But what’s all the fuss about them being so powerful? Monads are able to solve all the problems with pure functional programming, like side effects and state, how is this possible?

The answer is, that functors can enhance, or embellish, values. Taking our picture of containers, think about putting extra notes on the container, or even equip the container with some elaborated machinery, which does fancy thing, each time the content of the container is changed…

I’ll end with an relatively simple example of such a monad: The task
will be to log changes on a value. So we will have functions that not
only operate on the value but in addition create messages. These
messages shall be aggregated, so that, together with the final result
after an arbitrary number of operations, we will also have a complete
log of all operations performed.^{4}

So lets define our new monad `Logger`

:

```
module Logger (Logger(..), showLog)
where
import Control.Applicative (Applicative(..))
import Control.Monad (liftM, ap)
data Logger a = Logger {value :: a, logs :: [String]}
deriving Show
instance Functor Logger where
fmap = liftM
instance Applicative Logger where
pure x = Logger x []
(<*>) = ap
instance Monad Logger where
return = pure -- redundant since GHC 7.10 due to default impl
(Logger x ls) >>= f = let (Logger r l) = f x in
Logger r $ ls ++ l
showLog :: Logger a -> String
showLog = unlines . logs
```

There are a few things to say about the code, basically all the magic
happens in the definition of `>>=`

: The logging text, which is
already part of the container of the argument is merged with the
logging text, which the function `f`

provided with its result.

What might be confusing are the other instance definitions:

`Functor`

: as monads are functors it comes as no surprise that we must implement`fmap`

. The good thing:`fmap`

can be defined in terms of the monadic functions,^{5}which is already done by*Control.Monad*, where it is called`liftM`

(because it “lifts” the function into the monad), so we can simply use that.`Applicative`

: I have not written about applicative functors yet, and for now we can basically ignore them, but we have to define the instance as just like functor it’s a super class of monad. There are two mandatory functions which we must supply:`<*>`

, which again we can define it in terms of a function from Control.Monadand

`pure`

which happens to be identical to`return`

. Because Haskell’s default definition of`return`

in the`Monad`

class is`pure`

it makes sense to define`pure`

instead of defining`return`

directly, it’s the same thing anyway.

The function `showLog`

is just a convenience function I added for a
nice output of the logging information.

Now lets write a small program, using our new monad:

```
import Logger
type Account = Logger Int
newAccount :: Int -> Account
newAccount n = Logger n ["Initial balance: " ++ show n ++ " Credits"]
modifyAccount :: Int -> Int -> Account
modifyAccount n old = Logger (old + n) msg
where
msg
| n > 0 = ["Deposited " ++ show n ++ " Credits"]
| n < 0 = ["Withdrew " ++ show (negate n) ++ " Credits"]
| otherwise = ["Null operation"]
-- Use it:
main :: IO ()
main = do
let account = newAccount 0
>>= modifyAccount 42
>>= modifyAccount (-23)
>>= modifyAccount 256
>>= modifyAccount 25
putStrLn $ "Current balance: " ++ (show . value $ account)
putStrLn "Account's History:"
putStrLn $ showLog account
```

When run, it produces the output:

```
Current balance: 300
Account's History:
Initial balance: 0 Credits
Deposited 42 Credits
Withdrew 23 Credits
Deposited 256 Credits
Deposited 25 Credits
```

So what we achieved here, is a behavior as if the log was some kind of
global variable (or global state) each call of `modifyAccount`

appended its logging information to.

The `main`

function of the example shows something else, namely why
the default bind operator `>>=`

has its merits: consecutive functions
combined by bind can be understood as a series of “actions”, and in
this sense its easier to read code, where the order of execution and
the order of actions (functions) in the code are identical.

# Learn more

I have left out a lot of (partly important) details (and interesting theory) in this article. Now that I hopefully have shown to you, that monads in practice are nothing extraordinarily hard to understand, I’d highly recommend to study the work by others, to get a more complete picture of the topic:

as with any topic related to category theory my first recommendation will be

**Category Theory for Programmers**by Bartosz Milewski. You can read it on his Blog or watch it as ongoing series of talks, given by him self on YouTube.being an essential part of Haskell, there is a lot of material in the Haskell Wiki on monads

The

*Department of Computer and Information Science*(CIS) of the University of Pennsylvania has a nice summary on monads and especially the IO monad in their Haskell course

# Comment

As always, I’d like to hear from you. Especially I would be interested if this article helped you with understanding monads in Haskell or just increased the confusion…

# Kudos

I want to thank Bernhard Herzog for corrections and suggestions.

The other three monad laws are part of the formal definition of a monad, you can learn about them e.g. in the Haskell Wiki

^{[return]}Note, only the type of the “container” (the functor) needs to match, not the type of the “content”.

^{[return]}There are much more profound reasons for

`return`

, but like all the other deeper theoretical stuff, smarter people than I am already have explained them much better than I ever could. See the*Learn more*section of this article.^{[return]}Basically I nicked the idea from Bartosz Milewski’s lecture on Kleisli categories, which is no coincidence, as Kleisli categories are basically monads.

^{[return]}- e.g.
`fmap f = (=<<) (return . f)`

^{[return]}