Although we have already discussed what a monad is in general, the actual semantics—what it means for a given type to be a monad—depends on the type itself. Here we’ll go over a few of the more common examples of monadic types, how their `Monad`

instances are defined, and how they are used.

We are focusing on monads here, but for reference we will define the entire `Monad`

type ancestry (i.e. `Functor`

, `Applicative`

, and `Monad`

) together.

## IOlink

The `IO`

monad is perhaps the most (and least) boring of all; it really just wraps a value that can be chained together with other `IO`

operations with no actual semantics beyond interacting with the outside world of side effects. By definition its implementation is language-specific, so we will skip right on past to its more language-agnostic relatives.

## Optionallink

Good old `Optional`

is a `Monad`

used for chaining computations that may or may not have a result; after the first one that doesn’t, none of the following computations run.

```
data Optional a = Just a | Nothing
instance Functor Optional where
Just a) = Just (f a)
map f (Nothing) = Nothing
map f (
instance Applicative Optional where
= Just
pure
Just f) <*> (Just x) = Just (f x)
(Nothing <*> _ = Nothing
<*> Nothing = Nothing
_
instance Monad Optional where
Just a >>= f = f a
Nothing >>= _ = Nothing
```

Here’s what it looks like if you need to chain a bunch of `Optional`

results together without monadic operations:

```
foo : Optional a
bar : a -> Optional b
baz : b -> Optional c
= case foo of
resultPlain Just a -> case bar a of
Just b -> baz b
None -> None
None -> None
```

The repeated case matching can be replaced by a sequence of monad binds:

`= foo >>= bar >>= baz resultMonadic `

That looks much neater! If you check the definition of the `Optional`

monad, you can see how the null-checking structure is built in to the definition of `>>=`

, which is how we are able to skip so much repetition with monadic code.

## Listlink

The `List`

monad has a different meaning entirely, which is somewhat suprising since there is a tendency to believe that two instances of the same class should have similar semantics. That is true, in a sense, but the similarities are somewhat hard to spot. Here is how it is defined:

```
data List a = [] | a :: List a -- empty list, or head + tail
instance Functor List where
= []
map f [] :: xs) = f x :: (map f xs)
map f (x
instance Applicative List where
= x :: [] -- a list with one element; the tail is empty
pure x
<*> _ = []
[] <*> [] = []
_ :: fs) <*> xs = map f xs ++ (fs <*> xs) -- map each function over each argument and concat them all
(f
instance Monad List where
>>= _ = []
[] :: xs) >>= f = f x ++ (f >>= xs) -- concatenate results for each argument (x
```

To make sense of this, let’s start with `<*>`

. What is its type signature for lists?

`(<*>) : [a -> b] -> [a] -> [b]`

In other words, it takes a list of functions, and a list of arguments, and returns a list of results. This is why we have to do a lot of list concatenation: the obvious answer to what that type signature means is “apply each function to each possible argument.”

Now for bind:

`(>>=) : [a] -> (a -> [b]) -> [b]`

This takes a list of arguments, and a function from *one* argument to a list of results, and returns a list of results. Thus, the meaning of the list monad is to chain a bunch of functions that produce multiple results into one operation that produces *a lot* of results!

It may seem surprising that the same typeclass that gave us free null checks with `Optional`

gives us this weird concatenation behavior with `List`

s. But the main point is that in both cases, we are chaining function results together within a particular “container” type. How we interpret that chaining behavior just depends on what the type of container we’re using.

Using the `List`

monad is equivalent to repeated calls to `map`

and `flatten`

:

```
foo : [a]
bar : a -> [b]
baz : b -> [c]
flatten : [[x]] -> [x]
= []
flatten [] :: xss) = xs ++ flatten xss
flatten (xs
= flatten (map baz (flatten (map bar foo)))
resultPlain
= foo >>= bar >>= baz resultMonadic
```

## Eitherlink

The `Either`

type is another odd one. It takes two type parameters:

`data Either a b = Left a | Right b`

From this it should be clear that it simply represents a value that can be one of two possible types. The weirdness comes when we realize that things like `Functor`

can only map over one type parameter ^{1}:

```
instance Functor (Either a) where
Left e) = Left e
map f (Right a) = Right (f a)
map f (
instance Applicative (Either a) where
= Right x
pure x
Right f) <*> (Right x) = Right (f x)
(Left e) <*> _ = Left e
(<*> (Left e) = Left e
_
instance Monad (Either a) where
Right x) >>= f = f x
(Left e) >>= _ = Left e (
```

If you work out the type signature for `map`

over `Either a b`

, you’ll find that it looks like

`map : Either a b -> (b -> c) -> Either b c`

This is why we can’t do anything with a `Left`

value other than leave it alone. All of this is backstory for the main point, which is that `Either`

is generally used for operations that can “error out”, where a `Left`

value wraps an error and a `Right`

value wraps a successful result.

The non-monadic version is rather like `Optional`

, where we have to do a bunch of nested pattern matching to “short-circuit” the computation when a `Left`

value appears.

```
foo : Either err a
bar : a -> Either err b
baz : b -> Either err c
= case foo of
resultPlain Right a -> case bar a of
Right b -> baz b
Left e -> Left e
Left e -> Left e
= foo >>= bar >>= baz resultMonadic
```

## Readerlink

`Reader e a`

is the type of computations that all need access to some kind of shared configuration or other environment `e`

and produce a result of type `a`

. This is just another way of saying it’s a synonym for functions from `e`

to `a`

:^{2}

```
type Reader e a = (e -> a)
instance Functor (Reader e) where
= (.) -- function composition!
map
instance Applicative (Reader e) where
= const -- const x makes a "constant function" that always returns x
pure
<*> g = \e -> f e (g e) -- thread the environment to both Readers
f
instance Monad (Reader e) where
>>= g = \e -> g (f e) e -- thread the environment through the input and the output f
```

Those definitions are really weird, and to be honest I had to work them out via their type signatures. This is an excellent exercise in programming with types, so let’s go over how that works!

First, for `map`

, we should have

`map : (a -> b) -> Reader e a -> Reader e b`

which is to say,

`map : (a -> b) -> (e -> a) -> (e -> b)`

This is how we know that this is the same as function composition - it’s the same type signature, and that’s really the only way to achieve this type in general!

Now for `pure`

, we have

`pure : a -> (e -> a)`

This says “give me an `a`

, and I’ll give you a function that returns a `a`

for any input `e`

.” Once again, there’s only one option, which is the `const`

function:

```
const : a -> (e -> a)
= \_ -> x const x
```

Now for a more interesting one, we have applicative apply:

`(<*>) : Reader e (a -> b) -> Reader e a -> Reader e b`

which resolves to

`(<*>) : (e -> a -> b) -> (e -> a) -> (e -> b)`

We know that the end result needs to be a function of `e`

, so we’ll start there:

`<*> g = \e -> ??? f `

We can plug that `e`

into `g`

to get an `a`

, and then we can get the `b`

we are looking for by plugging both of those into `f`

:

`<*> g = \e -> f e (g e) f `

Hopefully the meaning of this is starting to become clear, in the context of computations that refer to a common environment `e`

. Here `f`

is a function that takes the environment *and another argument*, and `g`

is a function that takes the environment and produces a value that can be plugged into `f`

. All we had to do was figure out how to socket all these things into the right places to achieve the type we wanted.

Finally, monad bind:

`(>>=) : Reader e a -> (a -> Reader e b) -> Reader e b`

i.e.

`(>>=) : (e -> a) -> (a -> e -> b) -> (e -> b)`

Once again, we start with a function from `e`

:

`>>= g = \e -> ??? f `

Now, however, we’re a little backwards from what we used for `(<*>)`

. We plug the `e`

into `f`

to get an `a`

, and then we can plug *that* into `g`

along with `e`

(again) to produce the `b`

:

`>>= g = \e -> g (f e) e f `

The point of the `Reader`

monad is to save on constantly passing the environment down into sub-steps of a larger computation, similarly to how it saves us from having to constantly pattern-match on `Optional`

cases:

```
foo : Reader e a
bar : a -> Reader e b
baz : b -> Reader e c
= baz (bar (foo e) e) e
resultPlain
= (foo >>= bar >>= baz) e resultMonadic
```

In the monadic version, we only needed to explicitly pass the `e`

parameter once! Of course, in this simple example it hardly made a difference, but for more complex systems, this can be a huge saving in readability.

## Writerlink

`Writer o a`

is used for operations that successively append to a stream of output data `o`

, such as a record of which steps were taken or an incremental parser, in addition to the result type `a`

of each step. It can easily be implemented as a tuple:

```
type Writer o a = (o, a)
instance Functor (Writer o) where
= (o, f a) -- map the value, leave the accumulated value alone map f (o, a)
```

The `Functor`

instance is easy enough, but we need something extra for `Applicative`

and `Monad`

; we’re missing a way to start the accumulated output with `pure`

, and add them together across each step in our computation with `(<*>)`

. Luckily, we already have a way to define those two operations: the output just needs to be a `Monoid`

!

```
instance (Monoid o) => Applicative (Writer o) where
= (empty, x) -- start with an empty accumulator
pure x
<*> (o2, x) = (o1 <> o2, f x) -- concat accumulators, apply the function to the value
(o1, f)
instance (Monoid o) => Monad (Writer o) where
>>= f = let (o2, y) = f x in (o1 <> o2, y) -- concat accumulators, carry forward the output value (o1, x)
```

Here is how a chain of `Writer`

operations might look without and with monadic operations. For concreteness, I will actually use a list of `String`

values as the accumulator type:

```
aValue : a
bValue : a -> b
cValue : b -> c
foo : Writer [String] a
= (["called foo"], aValue)
foo
bar : a -> Writer [String] b
= (["called bar"], bValue a)
bar a
baz : b -> Writer [String] c
= (["called baz"], cValue b)
baz b
= let
resultPlain = foo
(o1, a) = bar a
(o2, b) = baz b
(o3, c) in (o1 ++ o2 ++ o3, c)
= foo >>= bar >>= baz resultMonadic
```

In both cases, the accumulated output acts like a log indicating the order that the functions were called: `["called foo", "called bar", "called baz"]`

.

## Statelink

Our final example of a generic monad is `State`

: the type of computations that update some kind of running “state” in addition to producing a output. This can be represented as a function from an initial state to a tuple of the final state and the output:

```
type State s a = s -> (s, a)
instance Functor (State s) where
= \s -> let (s, x) = st s in (s, f x) -- leave the state unchanged
map f st
instance Applicative (State s) where
= \s -> (s, x) -- leave the state unchanged and just return the given value
pure x
<*> stx = \s -> let
stf = stf s -- run the first computation to get the function and a new state
(s1, f) = stx s1 -- run the second, with the updated state from the first, to get the value and another new state
(s2, x) in (s2, f x) -- put them together with the final state
instance Monad (State s) where
>>= f = \s -> let
st = st s -- run the first thing to get a new state and its value
(s1, x) in f x s1 -- run the bound function with that value, then plug in the new state
```

There isn’t much trickiness here; we just need to make sure we’re carrying the intermediate state changes forward through each step of the computation.

If you really need to be able to map over both, there is a

`Bifunctor`

typeclass that will do that for you. We will leave that for [Advanced Typeclasses][advanced-typeclasses].↩︎Haskell programmers may find my use of

`type`

here somewhat unsettling, because in that language this would have to be defined in a`newtype`

in order to allow it to get its own typeclass instances. Here, however, we are not restricted by the need to make a compiler understand our meaning, so I am doing away with all of that extra effort of unwrapping and rewrapping newtype instances, with e.g.`runReader`

for the sake of human readability.↩︎