### Introduction

In a philosophy class in college, I remember learning the idea that in order to understand something, you can’t simply study it. For example, if you study the heart, you’ll understand the function of the valves, what causes the muscle to relax and contract, and so on, but you’ll have no idea *what* a heart is and what its purpose is. In order to learn that, you need to study the human body.

I’m going to take the same approach to `Monad`

s and `Functor`

s (and hopefully later `Applicative`

). I hope this doesn’t turn in another Monads are Burritos. I’ll avoid as much as possible type signatures and such so as not to obscure the main point.

### Containers

Two scary concepts in Haskell, `Functor`

s and `Monad`

s, both deal with containers. These aren’t as limited as containers from a language like Java. There, containers are linked lists, arrays maps, sets; some way of managing collections of stuff. In Haskell, we use containers to represent actions, logging, and- our topic today- things which *might* exist. I’m speaking about `Maybe`

.

I’ve chosen `Maybe`

since I find it easy to think about. You either have `Just`

a result, or `Nothing`

. To further simplify, we’ll only deal with `Maybe Int`

; a number that might exist.

How can such a thing occur? Let’s say these numbers represent the price for an item, given in cents. We might have a `getPrice`

function which takes an `Item`

as an argument. If a `Toothbrush`

costs $1.25, then the function would return `Just 125`

.

On the other hand, say you don’t have a price for `Toothpaste`

. Then the function would return `Nothing`

. (Think for a moment how you’d deal with this in Java, should a 0 represent unknown? What if you have a buy one-get one free sale? Use -1? You’ll have to remember to check for it everywhere. But I digress.)

### Monads

Anyway, let’s now say that you have another function to add tax onto the purchase price. It doesn’t deal with `Maybe`

s; it adds 5% to an `Int`

. But our `getPrice`

function returns a `Maybe Int`

. How can we stick these two functions together (ie, compose them)?

This is where we can use the trusty old `Monad`

. Let’s start with `do`

notation:

` `

getPriceWithTax item = do price <- getPrice item return $ addTax price

That’s a little verbose for something so simple. Let’s drop the `do`

:

` `

getPriceWithTax item = getPrice item >>= return . addTax

Great… except why the `return`

? We have two types at play: `Int`

and `Maybe Int`

. When dealing with one-argument functions, you get four possible function signatures:

`Int -> Int`

`Int -> Maybe Int`

`Maybe Int -> Int`

`Maybe Int -> Maybe Int`

The third option is unwrapping a contained value; it is not a topic for `Monad`

s or `Functor`

s, so ignore it for now. (If you care, look up `fromJust`

.) The first option is a regular old function, like `addTax`

. Option 2 is like `getPrice`

: it ends up wrapping a container. (We’ll address option 4 later.)

### Composition

In order to compose two functions, the output of one must be the same type as the input of the other. With containers, we in general can only add containers, not take them away. So in our `getPriceWithTax`

function above, we have `getPrice`

returning a `Maybe Int`

, and `addTax`

taking a plain `Int`

.

To make them compatible, one of them will have to change. Guess which? That’s right, we need to make `addTax`

take a `Maybe Int`

instead of an `Int`

. Also, since we can’t remove the container in the middle, we end up returning a `Maybe Int`

as well, which leads us to option 4 above.

Creating an option 4 function is where the `Monad`

ic bind function (>>=) comes in handy. It converts an contained -> contained function into a contained -> contained one. This gives us back composibility! But wait: `addTax`

returns an uncontained value. No problem: we just add a `return`

to make `addTax`

return contained values.

### Functors FTW

You might be thinking that it’s kind of silly to do business this way, and I’ll agree with you. What we **really** want is a way to convert totally uncontained functions (option 1) to totally contained ones (option 4). This is what `Functor`

s are for. A `Functor`

has a single function, `fmap`

, which does exactly that. So our code becomes:

` `

getPriceWithTax3 item = addTax `fmap` getPrice item

### Monads are still good

Now, there are times- many of them- when you’ll need the full power of `Monad`

s to deal with things. I hope to address that in a future post. But for now, the moral is: if you are using return with `Monad`

ic bind, you might want to consider `fmap`

instead.

June 5, 2009 at 5:32 pm |

“In a philosophy class in college, I remember learning the idea that in order to understand something, you can study it.”

Wah? The following sentences seem to assume some clause or idea that didn’t make it into this sentence.

‘out topic today- things which might exist.’

our.

“The third option is unwrapping a contained value; it is not a topic for Monads or Functors, so ignore it for now. (If you care, look up fromJust.) ”

Might mention why – fromJust is partial and thus evil.

June 7, 2009 at 4:17 am |

“In order to learn that, you need to study the human body.”

Does this have a name ? ( Explaining something by placing it into context / framework / system )

June 19, 2009 at 3:01 am |

fromJust is not “evil”. it is a very important concept.

You have to look at it as a membership relation:

If dealing with lists, this relation R relates x (of type A) and L (of type [A]), written x R L, if x is an element of L (elem funcion). Similarly for sets.

In Maybe, x (of type A) is related to M (of type Maybe A) if and only if M = Just x

Unfortunately, this is not really how fromJust is defined in Haskell, but the concept (of unwrapping something) is essential.