# Part 6: Monad Transformers

In the past few parts of this series, we’ve learned a lot of new monads. In part 3 we saw how common things like `Maybe`

and `IO`

can be monads. Then in part 4 and part 5 we learned about the `Reader`

, `Writer`

, and `State`

monads. With all these monads under out belt, you might be wondering how we can combine them. The answer, as we’ll discover in this part, is with monad transformers!

As you understand monads more and more, you’ll unlock many new Haskell abilities. But you still need some idea of the Haskell libraries that will let you exercise these! Be sure to download our Production Checklist to learn about some of these libraries!

## Motivating Example

Earlier in this series, we saw how the maybe monad helped us avoid **triangle of doom** code patterns. Without it, we had to check each function call for success. However, the examples we looked at were all **pure code examples**. Consider this:

```
main :: IO
main = do
maybeUserName <- readUserName
case maybeUserName of
Nothing -> print “Invalid user name!”
Just (uName) -> do
maybeEmail <- readEmail
case maybeEmail of
Nothing -> print “Invalid email!”
Just (email) -> do
maybePassword <- readPassword
Case maybePassword of
Nothing -> print “Invalid Password”
Just password -> login uName email password
readUserName :: IO (Maybe String)
readUserName = do
str <- getLIne
if length str > 5
then return $ Just str
else return Nothing
readEmail :: IO (Maybe String)
...
readPassword :: IO (Maybe String)
...
login :: String -> String -> String -> IO ()
...
```

In this example, all our potentially problematic code takes place within the IO monad. How can we use the `Maybe`

monad when we’re **already in another monad**?

## Monad Transformers

Luckily, we can get the desired behavior by using **monad transformers** to **combine monads**. In this example, we’ll wrap the IO actions within a transformer called `MaybeT`

.

A monad transformer is fundamentally a **wrapper type**. It is generally parameterized by another monadic type. You can then run actions from the inner monad, while adding your own customized behavior for combining actions in this new monad. The common transformers add `T`

to the end of an existing monad. Here’s the definition of `MaybeT`

:

```
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance (Monad m) => Monad (MaybeT m) where
return = lift . return
x >>= f = MaybeT $ do
v <- runMaybeT x
case v of
Nothing -> return Nothing
Just y -> runMaybeT (f y)
```

So `MaybeT`

itself is simply a newtype. It in turn contains a wrapper around a `Maybe`

value. If the type `m`

is a monad, we can **also make a monad out of** `MaybeT`

.

Let’s consider our example. We want to use `MaybeT`

to wrap the `IO`

monad, so we can run IO actions. This means our new monad is `MaybeT IO`

. Our three helper functions all return strings, so they each get the type `MaybeT IO String`

.
To convert the old `IO`

code into the `MaybeT`

monad, all we need to do is wrap the `IO`

action in the `MaybeT`

constructor.

```
readUserName :: MaybeT IO String
readUserName = MaybeT $ do
str <- getLIne
if length str > 5
then return $ Just str
else return Nothing
readEmail :: MaybeT IO String
...
readPassword :: MaybeT IO String
...
```

Now we can wrap all three of these calls into a single monadic action, and do a **single pattern match** to get the results. We’ll use the `runMaybeT`

function to unwrap the `Maybe`

value from the `MaybeT`

:

```
main :: IO ()
main = do
maybeCreds <- runMaybeT $ do
usr <- readUserName
email <- readEmail
pass <- readPassword
return (usr, email, pass)
case maybeCreds of
Nothing -> print "Couldn't login!"
Just (u, e, p) -> login u e p
```

And this new code will have the proper short-circuiting behavior of the Maybe monad! If any of the read functions fail, our code will immediately return `Nothing`

.

## Adding More Layers

Here’s the best part about monad transformers. Since our newly created type is a monad itself, we can wrap it inside **another transformer**! Pretty much all common monads have transformer types in the same way the `MaybeT`

is a transformer for the ordinary `Maybe`

monad.

For a quick example, suppose we had an `Env`

type containing some user information. We could wrap this environment in a **Reader**. However, we want to still have access to `IO`

functionality, so we’ll use the `ReaderT`

transformer. Then we can wrap the result in `MaybeT`

transformer.

```
type Env = (Maybe String, Maybe String, Maybe String)
readUserName :: MaybeT (ReaderT Env IO) String
readUserName = MaybeT $ do
(maybeOldUser, _, _) <- ask
case maybeOldUser of
Just str -> return str
Nothing -> do
-- lift allows normal IO functions from inside ReaderT Env IO!
input <- lift getLine
if length input > 5
then return (Just input)
else return Nothing
```

Notice we had to use `lift`

to run the IO function `getLine`

. In a monad transformer, the lift function allows you to run actions in the underlying monad. So using `lift`

in the `ReaderT Env IO`

action allows `IO`

functions. Within a `MaybeT (ReaderT Env IO)`

function, calling `lift`

would allow you to run a `Reader`

function. We don’t need this above since the bulk of the code lies in `Reader`

actions wrapped by the `MaybeT`

constructor.

To understand the concept of lifting, think of your monad layer as a stack. When you have a `ReaderT Env IO`

action, imagine a `Reader Env`

monad on top of the `IO`

monad. An IO action exists on the bottom layer. So to run it from the upper layer, you need to **lift** it up. If your stack is more than two layers, you can lift **multiple times**. Calling `lift`

twice from the `MaybeT (ReaderT Env IO)`

monad will allow you to call `IO`

functions.

It’s inconvenient to have to know how many times to call lift to get to a particular level of the chain. Thus **helper functions** are frequently used for this. Additionally, since monad transformers can run several layers deep, the types can get complicated. So it is typical to use type synonyms liberally.

```
type TripleMonad a = MaybeT (ReaderT Env IO) a
performReader :: ReaderT Env IO a -> TripleMonad a
performReader = lift
performIO :: IO a -> TripleMonad a
performIO = lift . lift
```

## Typeclasses

As a similar idea, there are some typeclasses which allow you to make certain **assumptions about the monad stack** below. For instance, you often don’t care what the exact stack is, but you just need `IO`

to exist somewhere on the stack. This is the purpose of the `MonadIO`

typeclass:

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

We can use this behavior to get a function to print even when we don’t know its **exact monad**:

```
debugFunc :: (MonadIO m) => String -> m a
debugFunc input = do
liftIO $ print “Interpreting Input: “ ++ input
…
```

One final note: You **cannot**, in general, **wrap another monad** with the **IO monad** using a transformer. You can, however, make the other monadic value the return type of an IO action.

```
func :: IO (Maybe String)
-- This type makes sense
func2 :: IO_T (ReaderT Env (Maybe)) string
-- This does not exist
```

## Summary

Now that you know how to combine your monads together, you’re almost done with understanding the key concepts of monads! You could probably go out now and start writing some pretty complex code! But to truly master monads, you should know how to make your own, and there’s one final concept that you should understand for that. This is the idea of type "laws". Each of the structures we’ve gone over in this series has a series of laws associated with it. And for your instances of these classes to make sense, they should follow the laws! Check out part 7 to make sure you know what’s going on!

Now that you can write some pretty complex code, you need to know some of the libraries that will help you use it! Download our Production Checklist for a summary of some awesome libraries to help you apply your skills! Haskell has many tools for tasks like building web APIs and accessing databases. Now that you know all about monads, you can use these quite easily!