This post is part of the series Monad Transformers
1. Monad Transformers – Part 1: An Introduction

Once you’ve learned some basic of “Monad”. The next step in the journey is “Monad Transformers”. In this series, we’ll use the basic building block of Haskell to learn about “Monad Transformers”.

## The basic

Let’s start with the most basic possible Monad. The `Maybe` monad. Here’s the type signature for `Maybe` type:

``````Maybe a :: Nothing | Just a
``````

We use `Maybe` to represent an optional value. For example. The `div :: a -> a -> a` function will throw exception when using `0` as divisor.

``````> 1 `div` 0

-- Exception: divide by zero
``````

So, instead we could use `Maybe` type to turn `div` into total function.

``````div' :: Int -> Int -> Maybe Int
div' x 0 = Nothing
div' x d = Just \$ x `div` d
``````

With this, we can safely do a division by using any number as divisor!

``````> 1 `div'` 0

Nothing
``````

## Going further

Next, let’s go one step further. We will still be working with optional value (`Maybe a`). But this time, we’ll put it in another type.

### 1. List of optional values `[Maybe a]`

If we want to apply some transformation to these list of optional values. How could we do that? Let’s think about it a little bit.

We all know that we could use `map` to apply a function to a list of values e.g. `[a]`:

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

But what about list of optional values (`[Maybe a]`)?

``````(a -> b) -> [Maybe a] -> [Maybe b]
``````

There’re many ways to implement this. But in order to demonstrate the purpose of Monad Transformers. We’ll implement it via `do` notation with binding arrow (`<-`).

``````1map' :: (a -> b) -> [Maybe a] -> [Maybe b]
2map' f xs = do
3  x <- xs          -- 1
4  return \$ f <\$> x -- 2``````
Example 1.1: List of optional values (`[Maybe a]`).

1. The first thing we do is to use `<-` arrow to access `Maybe a` inside `[]`. i.e. `x :: Maybe a`.
2. Since `x` is `Maybe a`, we can use `fmap :: (a -> b) -> f a -> f b` to apply function to `a` directly.

Let’s see it in action!

``````> map' (+2) [Just 1, Just 5, Nothing]

[Just 3, Just 7, Nothing]
``````

### 2. Action with optional value `IO (Maybe a)`

We’ll write a simple program that asks user to choose whether to continue or stop.

`````` 1import Data.Char (toLower)
2
3accept :: IO (Maybe String)
4accept = do
5  s <- getLine
6  if map toLower s == "y"
7    then return \$ Just s
8    else return Nothing
9
10main = IO ()
11  result <- accept -- 1
12  case result of   -- 2
13    Nothing -> putStrLn "Quit"
14    Just s  -> putStrLn \$ s ++ ": Continue"
``````

Example 2.1: `IO` with optional value (`IO Maybe a`).

1. This is similar to what we did on previous example on `[Maybe a]`. We use binding arrow (`<-`) to access `Maybe String` value.
2. Next, we perform pattern matching on the result.

## Can you spot a pattern?

We might have noticed that there’re some kind of repetitive pattern here. Whenever we want to get a hold of our optional value (`Maybe a`). We have to always call `<-` arrow first. Even though, we don’t really care what the outermost types are (In our example, `[]` and `IO` respectively).

Before we introduce our first “Monad transformers”. Let’s take a sneak peek of the new Monad transformers version of our previous examples!

List of optional values

We can see that our transformer version on the right doesn’t need to call `x <- xs` to get access to `Maybe a` any more:

``````map' f xs = do
x <- xs -- 1. x :: Maybe a
return \$ f <\$> x
``````

Before

``````map'' f xs = f <\$> xs
-- `f` operates on `a` directly.
--
``````

After

Action with optional value

Same thing here. The `result <- accept` call on the right, now returns `String` directly. No need for us to perform a pattern matching on the result like we did previously (before, it returns `Maybe String`):

``````result <- accept -- 1. result :: Maybe String
case result of   -- 2.
Nothing -> putStrLn "Quit"
Just s  -> putStrLn \$ s ++ ": Continue"
``````

Before

``````result <- accept' -- 1. result :: String
lift \$ putStrLn \$ result ++ ": Continue"
--
--
``````

After

## Summary

In part 1. We started by showing what happened when we need to wrap our monadic values (i.e. `Maybe a`) in another type (`[]` and `IO`). We also showed a glimpse of the transformer version that we’ll cover in next post.

In next post, we’ll take a look in more details on how does it actually work.