# Monad Transformer

## Motivation

As we saw in previous posts, each kind of monad has their specific purpose, `Maybe`

and `Either`

for error handling, `Writer`

for recording and combining output, `Reader`

for accessing global environment etc. But solving one problem may need several monad abstractions, for example we may need both error handling and state manipulation in a single program. How do we do that?

## Introduction

Consider a simple example, we running a program that needs both io operation and error handling, so we use `IO`

hand `Maybe`

here. We may want to write the type as follow.

```
type IOMaybe a = IO (Maybe a)
```

It’s perfectly io with error handling huh. It works with no doubt, but problem of `Maybe`

-without-monad arises again here when we want to chaining the actions, and probably even worse than we thought.

```
actionA :: IO (Maybe A)
actionB :: A -> IO (Maybe B)
actionC :: B -> IO (Maybe C)
chainAction :: IO (Maybe C)
chainAction = do
ma <- actionA
case ma of
Just a -> do
mb <- actionB a
case mb of
Just b -> actionC b
Nothing -> return Nothing
Nothing -> return Nothing
```

We avoid pattern matching every time when we want to extract value from `Maybe`

by making it a monad. But the monad instance of `Maybe`

doesn’t help us here, it only works for expressions that have `Maybe`

as the monad of the result, but here the `IO`

dominates the `do`

block, and unfortunately `Maybe`

s are the values inside of `IO`

, so we can do nothing about that.

Or can we?

### IOMaybe as a monad

Look at the code again, we saw similar patterns over and over.

- We run an IO action, extract maybe object from it.
- We pattern match on the maybe object
- If it contains a value, we extract it, or just
`return Nothing`

otherwise

So all we need is a tool that abstract this process out! Yes, let’s make it a monad.

```
newtype IOMaybe a = IOMaybe { runIOMaybe :: IO (Maybe a) }
instance Functor IOMaybe where
fmap f = IOMaybe . fmap (fmap f) . runIOMaybe
instance Applicative IOMaybe where
pure = IOMaybe . pure . pure
(IOMaybe iomf) <*> (IOMaybe ioma) = IOMaybe $ liftA2 (<*>) iomf ioma
instance Monad IOMaybe where
return = pure
(IOMaybe iom) >>= f = IOMaybe $ do
m <- iom
case m of
Just a -> runIOMaybe $ f a
Nothing -> return Nothing
```

Then we can use `IOMaybe`

like this!

```
actionA :: IOMaybe A
actionB :: A -> IOMaybe B
actionC :: B -> IOMaybe C
chainAction :: IOMaybe C
chainAction = do
a <- actionA
b <- actionB a
actionC b
```

Great! The pattern matching hell is completely gone!

`MaybeT`

, the Maybe Transformer

But wait, when you are looking at the monad definition above, does it have anything to do with `IO`

at all? Err, I mean … we may replace IO to any other monad, right? Let’s do this.

```
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance Functor m => Functor (MaybeT m) where
fmap f = MaybeT . fmap (fmap f) . runMaybeT
instance Applicative m => Applicative (MaybeT m) where
pure = MaybeT . pure . pure
(MaybeT mf) <*> (MaybeT ma) = MaybeT $ liftA2 (<*>) mf ma
instance Monad m => Monad (MaybeT m) where
return = pure
(MaybeT m) >>= f = MaybeT $ do
ma <- m
case ma of
Just a -> runMaybeT $ f a
Nothing -> return Nothing
```

Nothing really change here except for parameterizing the monad, then `IOMaybe`

is just…

```
type IOMaybe = MaybeT IO
```

### the Monad Transformer

The `MaybeT`

we define above is just one of the monad transformers. It’s a convention to name a monad transformer of `SomeMonad`

to `SomeMonadT`

.

The maybe transformer transforms another monad to a maybe-like monad and embedding the behaviour **into** that monad. As we saw, we embeded the `Maybe`

into the `IO`

so that we can only extract value when there is any, and returning `Nothing`

otherwise. As a result we add new functionality into the monad while preserving the original. We pick `MaybeT`

as an example, but you now probably have some rought idea how other monad transformer works.

And notice that the “monad slot” of the `MaybeT`

itself can be another monad transformer, i.e. the monad transformer is defined recursively, which enable us to merge more than two monads together.

## Monad Lifting

### Motivation

Honestly, when I said something like “add new **while preserving the original**”, I lied, well, not completely though. We showed that `IOMaybe`

can be used like a `Maybe`

, where does `IO`

goes then, how do we launch a normal IO action then?

Since something like this

```
chainAction :: IOMaybe C
chainAction = do
a <- actionA
putStrLn "actionA" -- Couldn't match type ‘IO’ with ‘MaybeT IO’
b <- actionB a
actionC b
```

doesn’t work quite obviously, so we may want to fix that line with…

```
MaybeT $ Just <$> putStrLn "actionA complete"
```

But Every Single Time??

```
chainAction :: IOMaybe C
chainAction = do
a <- actionA
MaybeT $ Just <$> putStrLn "actionA complete"
b <- actionB a
MaybeT $ Just <$> putStrLn "actionB complete"
c <- actionC b
MaybeT $ Just <$> putStrLn "actionC complete"
return c
```

This is a serious problem.

### Lifting original monad to new context

Everytime we need to copy-&-paste something, we gotta abstract it out. The problem is how to choose an abstraction.

The problem here is that since we conceptually cover the `IO`

with `MaybeT`

, so plain IO action (monad) doesn’t work here. So we can define a function for `MaybeT`

to “wrap” the `MaybeT`

around the inner monad.

```
liftMaybeT :: Monad m => m a -> MaybeT m a
liftMaybeT = MaybeT . fmap Just
```

then there’re a lot less boilerplates

```
chainAction :: IOMaybe C
chainAction = do
a <- actionA
liftMaybeT $ putStrLn "actionA complete"
b <- actionB a
liftMaybeT $ putStrLn "actionB complete"
c <- actionC b
liftMaybeT $ putStrLn "actionC complete"
return c
```

`MonadTrans`

Actually, the “lifting” abstraction for `MaybeT`

is also needed by other monad transformers, so why not provide a consistent interface for that, and that’s `MonadTrans`

.

```
class MonadTrans t where
lift :: Monad m => m a -> t m a
```

`MonadTrans`

only has a single method used for lifting inner monad (in terms of the type of transformer) to the transformer context. The lifting action should satify the following laws:

- Identity:
`lift . return`

===`return`

- Associativity:
`lift (m >>= f)`

===`lift m >>= (lift . f)`

which basically said the lifting operation shouldn’t introducing new non-trivial context of the transformer.

Then we can define the `MaybeT`

as an instance of `MonadTrans`

```
instance MonadTrans MaybeT where
lift = MaybeT . fmap Just
```

At last we change all `liftMaybeT`

to `lift`

then we’re done.

`MonadIO`

If you looking at codes involving monad transformers and `IO`

, you often see `liftIO`

instead of the simple `lift`

, so I think it’s worth mentioning this here, although it’s not completely necessary.

The motivation of `LiftIO`

is that, since there is no transformer for `IO`

, so that `IO`

is always appear as the innermost monad in the transformer stack, that is, the outermost monad after running the transformer. Being the bottom of the transformer stack, which means it usually need several times of lifting like…

```
type SomeBigTransformerStack = StateT S (ListT (MaybeT IO))
iJustWantToHelloWorld :: SomeBigTransformerStack ()
iJustWantToHelloWorld = lift $ lift $ lift $ putStrLn "hhhhello..?"
```

It ain’t good.

So we may want to lift the inner most `IO`

to the monad directly instead of lifting it multiple times. So we define another interface.

```
class Monad m => MonadIO m where
liftIO :: IO a -> m a
```

which allow whatever monad (transformer, usually) being an instance of `MonadIO`

to lift a plain IO operation to itself.

And of course, the base case, `IO`

itself is a `MonadIO`

```
instance MonadIO IO where
liftIO = id
```

As for monad transformers, if the monad it wraps can lift IO operation, it can. Take `MaybeT`

as an example.

```
instance MonadIO m => MonadIO (MaybeT m) where
liftIO = lift . liftIO
```

As a convention, all `MonadIO`

instance is recursively defined for monad transformers. So the constraint deduction would converge to the `MonadIO IO`

base case if there’s a `IO`

sitting at the bottom of the transformer stack.

Here’s a cleaner io:

```
cleanerHelloWorld :: SomeBigTransformerStack ()
cleanerHelloWorld = liftIO $ putStrLn "hello world"
```

`ReaderT`

, `WriterT`

and `StateT`

I said in the last post, the `Reader`

, `Writer`

and `State`

in library aren’t exactly like that. Actually, they are all specialization of moand transformers. Let’s look at them closely.

```
newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
```

Observing that ordinary `Reader`

, `Writer`

and `State`

don’t have the `m`

part, so when we don’t actually need a monad when a monad is required, we use the trivial monad `Identity`

, (also trivial functor and applicative and many other thing), which is defined in `Data.Functor.Identity`

like this:

```
newtype Identity a = Identity { runIdentity :: a }
```

Just as the type name indicates, an `Identity`

of `a`

is just `a`

itself, except that it’s wrapped in a parameterized type (with kind `* -> *`

).

So the ordinary `Reader`

, `Writer`

, and `State`

```
type Reader r a = ReaderT r Identity a
runReader :: Reader r a -> r -> a
runReader m = runIdentity . runReaderT m
type Writer w a = WriterT w Identity a
runWriter :: Writer w a -> (a, w)
runWriter = runIdentity . runWriterT
type State s a = StateT s Identity a
runState :: State s a -> s -> (a, s)
runState m = runIdentity . runStateT m
```

Of course, all utility operations like `ask`

, `tell`

, `get`

, `put`

etc. should be altered to the monad transformer form. We would introduce them in the following section.

## the “Monadic Interface” in `MTL`

### Motivation

Lifting can be annoying, especially when there’re multiple things to lift at multiple layer of the stack. Let’s look at a trivial example.

Type signatures of `ask`

, `tell`

and `put`

in haskell base library is defined as:

```
ask :: Monad m => ReaderT r m r
tell :: Monad m => w -> WriterT w m ()
put :: Monad m => s -> StateT s m ()
```

No surprise huh? Let’s use them.

```
type RWS = ReaderT Int (WriterT String (State Char))
someAction :: RWS ()
someAction = do
env <- ask
lift $ tell "hello"
lift $ lift $ put 'a'
```

Here .. if we use `Reader`

, no lift is needed. For `Writer`

, 1 lift. For `State`

, 2 lifts. We know the number of lifting needed depends on the their position in the transformer stack. Although compiler always know how many lifts are needed in each case, it doesn’t feels very good, especially when code gets bigger, and there’re also other transformer stack with different order.

`liftIO`

solve this problem for `IO`

using the fact that `IO`

is always in the innermost postition, as long as all the transformers above of it support `liftIO`

, there’s always one liftIO without thinking.

So how do we solve this problem for other monads?

(for combination of `Reader`

, `Writer`

and `State`

, there’s a monad named `RWS`

combining and flattening the operation of all three monads, but it only works when you need exactly these three monads at the sametime, or you may provide trivial context (unit `()`

, for example) for either of the three as a work around.)

### Monadic Interfaces

#### the Interface

To get rid of `lift`

, we need utilities like `get`

and `put`

polymorphic, I mean, it can’t simply returns concrete monad transformer like `StateT`

, talking about polymorphism in haskell, how about making a typeclass?

```
class MonadState ??? where
get :: ???
put :: s -> ???
state :: (s -> (a, s)) -> ???
```

We need to have access to the state type `s`

in the class, but obviously the return value should be polymorphic. So we turn on the `{-# LANGUAGE MultiParamTypeClasses #-}`

language feature to allow us to declare multiple type parameters in a single typeclass:

```
class Monad m => MonadState s m where
get :: m s
put :: s -> m ()
state :: (s -> (a, s)) -> m a
```

Easy? Then we declare instances for the typeclass, of course we first want `StateT`

to be `MonadState`

. We should then turn on `{-# LANGUAGE FlexibleInstances #-}`

to allow us to declare a partially applied parameterized type to be a instance of typeclass. If you don’t know what I’m talking about, just ignore it.

```
instance Monad m => MonadState s (StateT s m) where
get = StateT $ \s -> return (s, s)
put s = StateT $ const (return ((), s))
```

#### the Functional Dependency

Great, let’s test it first. Say we want to convert the integer state to a string.

```
intToString :: State Int String
intToString = do
s <- get -- Error: Ambiguous type variable ‘a0’ arising from a use of ‘get’
return $ show s
```

Wait, what? We declared the instance for `StateT`

whose monad part (`m`

) is `StateT s m`

, and in this case `m`

should be `StateT Int Identity String`

, then `s`

should perfectly be `Int`

, what is ambiguous at all?

Let’s look at the typeclass and instance definition again, `MonadState`

itself **never** say: “if the second parameter is `StateT s m`

, then the first parameter must be `s`

, right? It’s perfectly legal to declare a instance `MonadState String (StateT s m)`

or something else, even there isn’t one now. So the compiler cannot resolve `s`

to `Int`

according to currently defined instance with the receiver being a polymorphic function (`show`

).

This problem is not trivial, and luckily we have another tool to solve it. We enable `{-# LANGUAGE FunctionalDependencies #-}`

, and change the definition of `MonadState`

:

```
class Monad m => MonadState s m | m -> s where
get :: m s
put :: s -> m ()
state :: (s -> (a, s)) -> m a
```

The `m -> s`

notation behind the bar has nothing to do with the function type. It declares the functional dependency over `m`

to `s`

, which means that for any type `m`

, with which there would be at most one type `s`

forms the instance of `MonadReader`

. The functional dependency effectively promise to the compiler that we would only declare at most one `MonadState`

instance for each `m`

. Now the `intToString`

above type checks, since compiler saw the `StateT`

instance declaration, and knew `s`

cannot be any other type but `Int`

.

#### other Instances

To make `StateT`

available for other monad transformers, we should declare other monad transformer. Borrowing the idea from instances of `MonadIO`

, we want to say: if `s`

and `m`

are instance of `MonadState`

, then `s`

and `SomeOtherTransformer m`

is `MonadState`

, so when we are using `SomeOtherTransformer`

, we can also use `get`

and `put`

to manipulate the state in the `State`

it directly or indirectly wraps. I copy and paste some instances of `MonadState`

here and you should have some feeling about how this works.

```
instance MonadState s m => MonadState s (MaybeT m) where
get = lift get
put = lift . put
state = lift . state
instance MonadState s m => MonadState s (ReaderT r m) where
get = lift get
put = lift . put
state = lift . state
instance (Monoid w, MonadState s m) => MonadState s (WriterT w m) where
get = lift get
put = lift . put
state = lift . state
-- more of them
```

Why not declare the instance like `instance (MonadTrans t, MonadState s m) => MonadState s (t m)`

once and for all? The reason is that in this case, the `MonadTrans`

is just enough for the `MonadState`

, but it’s not the general situations for monadic interfaces, so we’d better not treat the `MonadState`

specially.

#### Other interfaces

Of course, there are corresponding interfaces for `Writer`

, `Reader`

, `Except`

and `SomeOtherTransformer`

naming `MonadWriter`

, `MonadReader`

, `MonadExcept`

and `MonadSomeOtherTransformer`

. And they’re all compatible to every other transformers in the `MTL`

.

It’s a lot of work, of course. While since monad transformers are used a lot more often than created, the boilerplates are totally bearable, comparing to the complexity reduced of client code.

#### Finally

With all these effort, we finally get rid of appreciable amount of `lift`

s. The sample in the beginning of this section can be improved to:

```
type RWS = ReaderT Int (WriterT String (State Char))
someAction :: RWS ()
someAction = do
env <- ask -- these
tell "hello" -- all
put 'a' -- type checks
```

At this point you should convince yourself the trivial example above actually works. If you have any problem, you may consult the documentation and api of mtl.

## Other Notes about Monad Transformers

### the `ExceptT`

A basic transformer we didn’t introduce before is the `ExceptT`

, whose underlying monad is `Either`

. As we mentioned previously, the `Either`

provide the abstraction of “error handling”, `ExceptT`

and `MonadExcept`

provide more useful utilities of that, we can `throwError`

and `catchError`

, and have a feeling of doing imperative programming. But there’s nothing really complicated behind it, so I guess it’s ok for you (to implement that?).

### the stacking order matters

The stacking order of monad transformer affects the final result of program, for example

```
ListT Maybe a === Maybe [a]
MaybeT [] a === [Maybe a]
StateT s (Writer w) a === (s -> (s, a), w)
WriterT w (State s) a === s -> ((a, w), s)
-- etc.
```

So you should carefully choose correct monads and stack them in the correct order in terms of the meaning of your program. Especially when error handling is involved.

### user defined transformers

On the user perspective, if you insist on defining a new monad and used with other monad transformer in the `mtl`

library. You can simply place your monad at the bottom of the transformer stack without without extending the `mtl`

library.

And if you also your own monadic interface, and the number of instances you define depend on the purpose of your code (only a part of your program, or as a transformer library).

### Import paths

The monad transformers in haskell base library are under `Control.Monad.Trans.XXX`

, like `Control.Monad.Trans.State`

, and for some monads the library provide both strict and lazy version (the strictness and laziness is in terms of pattern matching), the lazy version is used by default, if you want to use the strict version, you should import something like `Control.Monad.State.Strict`

For `mtl`

, they are `Control.Monad.XXX`

like `Control.Monad.State`

, also, `mtl`

makes use of the strict and lazy versions of transformer in the base library, so it also provide `Control.Monad.XXX.Strict`

and `Control.Monad.XXX.Lazy`

if there are ones in the base library.

## Conclusion & What to do next?

In this post I covered some basic concept and implementation of the monad transformer, I hope those makes sense to you. In real-world, the reason way we seldom create monad ourselves is because of the flexibility of monad transformers mtl provide, we stack different monads with different order to encapusulate different semantic to our program. Such as an interpreter often includes the `State`

and `Except`

, command line tools often something sombining `IO`

and `Reader`

, server running constantly is something `State`

and `Writer`

etc.

The five posts in the series introduce almost everything of monad that I think is important for beginner of haskell and functional programming. And hopefully the word `monad`

doesn’t scare you any more.

Functional programming, haskell and monad are all extremely complex things, what I know and understand is only the tiniest bit among them. There’re more commonly-used monads I didn’t introduce here like `Parser`

and `Cont`

(Continuation), and a lot more about the monad typeclass family and so on. So the end of the series doesn’t mean an end at any degree.

Good luck from now.