*Monad Transformers*

- 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
```

`Option<T>`

.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 (`<-`

).

`map'`

as `map' = fmap . fmap`

instead. But here, we want to demonstrate the difference between a simple monad *vs.*transformer version.

**Example 1.1**: List of optional values (`[Maybe a]`

).- The first thing we do is to use
`<-`

arrow to access`Maybe a`

inside`[]`

. i.e.`x :: Maybe a`

. - 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`

).

- This is similar to what we did on previous example on
`[Maybe a]`

. We use binding arrow (`<-`

) to access`Maybe String`

value. - 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).

In example 1.1. We use `<-`

to extract `Maybe a`

out from `[]`

.

```
3 x <- xs -- 1
4 return $ f <$> x
```

Here again, in example 2.1. We use `<-`

to extract `Maybe a`

out from `IO`

.

```
11 result <- accept -- 1
12 case result of
```

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.