# Monad transformers

In my post about building a JSON REST API in Haskell, I glossed over monad transformers. That was unfortunate. Monad transformers are both useful and hard for me to wrap my head around. To help my solidify my understanding (and to fill the gap left by my other post) I’ll try to explain them here.

Before I can do that, I need to introduce a few monads. They are all simple and together they can be used to show how transformers work.

The first is `Identity`

. As the name implies, it does almost
nothing. Like the `identity`

function, it isn’t too useful by itself
but becomes it can be handy in certain situations. Here’s an example
of how to use it:

```
import Data.Functor.Identity (Identity, runIdentity)
type Output = Integer
anIdentity :: Identity Output
anIdentity = do
x <- return 3
let y = x * 2
return y
>>> runIdentity anIdentity
6
```

The next monad we’ll look at is `Reader`

. It adds some read-only
data. It can be a convenient way to add configuration information
to an otherwise pure function. Here’s how it looks in action:

```
import Control.Monad.Trans.Reader (Reader, ask, runReader)
type Input = Integer
type Output = String
aReader :: Reader Input Output
aReader = do
x <- ask
let s = "The input was " ++ show x
return s
>>> runReader aReader 3
"The input was 3"
```

Finally we’ll take a look at the `Writer`

monad. It is the
opposite of the reader monad. It adds write-only data. It is most
often used to add logging to a function. Like the reader, it is
easy to use:

```
import Control.Monad.Trans.Writer (Writer, tell, runWriter)
type Output = [String]
type Result = Integer
aWriter :: Writer Output Result
aWriter = do
let x = 3
tell ["The number was " ++ show x]
return x
>>> runWriter aWriter
(3,["The number was 3"])
```

Now that we’ve covered all the monads, there’s one more piece we
need for transformers. The `lift`

function takes a function
that works in one monad and allows you to use it in another. You
can `ask`

for something inside a `Reader`

, but if you’re in a
transformer stack that contains a reader, you have to `lift ask`

for it. It’s easier to understand through an example. So let’s build
up a monad transformer stack.

At the bottom will be an `Identity`

monad. It doesn’t really do
anything, but it lets us put more stuff on top of it. (Another
popular base is the `IO`

monad.) Above that, we’ll layer a `Reader`

monad. In real life this would probably contain some kind of
application configuration. For our purposes, it’ll hold a number.
And at the top we’ll have a `Writer`

monad. We’ll have it accumulate
a list of strings, which may be what you’d use it for in real life.

```
import Control.Monad.Trans.Class (lift)
import Data.Functor.Identity (Identity, runIdentity)
import Control.Monad.Trans.Reader (ReaderT, ask, runReader)
import Control.Monad.Trans.Writer (WriterT, tell, runWriter)
type Input = Integer
type Output = [String]
type Result = Integer
stack :: WriterT Output (ReaderT Input Identity) Result
stack = do
x <- lift ask
tell ["The input was " ++ show x]
return x
```

So that’s the whole stack. We can use the outer `Writer`

monad
directly with `tell`

. But we have to wrap calls to the inner `Reader`

monad with `lift`

. This is the crux of the power of monad transformers.
They allow you to use any monad in the stack with a single call to
`lift`

. Even if you have a stack of 10 monads, one `lift`

is all
you need to get all the way to the one you want.

The only downside is that you need to run all of these monads. Doing so can be a little tedious.

```
>>> let newReader = runWriterT stack
>>> let newIdentity = runReaderT newReader 3
>>> runIdentity newIdentity
(3,["The number was 3"])
```

This example is trivial, but I hope it shows how monad transformers work. They are a powerful way to combine monadic actions.