# Monads

A monad is defined by:

- the
`return`

operator - a type constructor
`m`

(see Types in Haskell) - the
`>>=`

operator, which is pronounced 'bind'

The `>>=`

operator has the following definition:

(>>=) :: m a -> (a -> m b) -> m b

The `return`

operator has the following definition:

return :: a -> m a

In the above, `m`

is a type constructor that takes one argument. Then, the `Monad`

class definition is:

class Monad m where (>>=) :: m a -> (a -> mb) -> mb return :: a -> m a

## 1. do notation

Calls to `>>=`

can be nested:

Just 3 >>= (\x -> Just 4 >>= (\y -> return x+y))

This can be re-written in do-notation as:

foo :: Maybe String foo = do x <- Just 3 y <- Just 4 return x+y

Note that on each line, `>>=`

is being used implictly

## 2. example: maybe monad

instance Monad Maybe where return x = Just x Nothing >>= f = Nothing Just x >>= f = f x

### 2.1. how to think about the `Maybe`

monad

What is the point of using monads here? The `Maybe`

provides a context for the computation. The computation, `f`

, that we want to do, only takes place if it's in the right context: namely the `Just`

context.

## 3. example: list monad

instance Monad [] where return x = [x] xs >>= f = concat (map f xs)

### 3.1. how to think about the `[]`

monad

You can think of `f`

as having a non-deterministic output – for a single value, it produces many values. Here, `f`

is also being executed in a non-deterministic context. Note that `f`

doesn't know that it is being executed in a non-determinisitc context. All of that is handled by how `>>=`

is written.

### 3.2. example: IO monad

An IO monad contains a value that has been obtained via an IO operation. So,

getLine :: IO String putStrLn :: String -> IO ()

can be combined like:

getLine >>= (\x -> putStrLn x)

Here, `x`

is the 'unpacked' result of the IO `getLine`

, which can be thought of as a box that goes out into the world and fetches a value. Under the hood, the `IO`

monad also introduces data dependencies in such a way that IO operations can be sequenced (see this wiki link).

#### 3.2.1. useful links

## 4. how should we think about monads?

Lots of interesting answers in this stack overflow post.

If we have functions:

f :: String -> Int g :: Int -> Float

It's pretty obvious how we should compose them using `(.)`

. But when we have:

f :: String -> Maybe Int g :: Int -> Maybe Float

how should we compose them? Monads specify how. It tells us that the composition of these two functions is the following:

\x -> f x >>= g

All the unpacking and re-packing has been handled by the join `>>=`

We can think of monads as tools for abstraction. Really, the code that we are interested in writing are the functions `f`

. We don't want our program cluttered up by all the code needed to handle composing these functions together. For `[]`

, we abstract away the glue code that handles concatenation of the results. For `Maybe`

, we abstract away the glue code that handles termination if `Nothing`

occurs.

### 4.1. contrast to functors

For a functor, the definition of `fmap`

is:

fmap :: (a -> b) -> f a -> f b

Notice that the function `(a -> b)`

only has access to the value `a`

. It can't specify anything about the output's *context*. For example, applying `fmap`

to a `Maybe`

will never change a `Just a`

to a `Nothing`

. In contrast, monads allow us to apply functions of the type `a -> M b`

, in which this is possible.

Originally, monads were not a subclass of applicative functors, but they are now.

## 5. Monad laws

### 5.1. left associativity

return x >>= f

is equivalent to `f x`

.

I think of `return x`

as the minimal containing box for `x`

. Then, binding `f`

to that box will unpack the value and then apply `f`

. This should be the same thing as just applying `f`

to `x`

.

Or: `return`

is a left-identity with respect to `>>=`

.

### 5.2. right identity

m >>= return

is the same thing as `m`

. Note that here, `m`

is a single concrete type, such as `Just String`

.

So, unpacking something from a monadic wrapper and then re-packing it in the minimal containing wrapper will result in the same thing as constructing the monad directly.

### 5.3. associativity

(m >>= f) >>= g

is the same as

m >>= (\x -> f x >>= g)

The first one is read as: apply `f`

to `m`

to get a new monadic value, and then apply `g`

to that new value.

The second one is read as: apply to `m`

, the function that unpacks `x`

, applies `f`

to `x`

to get a new monadic value and then applies `g`

to the new value.

## 6. Useful functions

### 6.1. replicateM

Applicative m => Int -> m a -> m [a]

Then, `replicateM 5 as`

is equivalent to:

do a1 <- as a2 <- as a3 <- as a4 <- as a5 <- as pure [a1,a2,a3,a4,a5]

### 6.2. sequence

The definition (from here):

sequence :: Monad m => [m a] -> m [a] sequence = foldr mcons (return []) where mcons p q = p >>= \x -> q >>= \y -> return (x:y)

`sequence`

takes a list of monadic computations and returns a list of their results, wrapped in a monad. Note that if using the IO monad, using `>>=`

will cause the IO action to run.