# Reverse Engineering the Monad

I've been banging my head up against understanding monads in Haskell for a while, but I'm now delighted to have finally cracked the puzzle. There are a myriad of tutorials and I find it highly unusual that the guides do not all point to You Could Have Invented Monads as to go-to tutorial. Where Dan Piponi (sigfpe) succeeds when others have failed is through demonstrating Monads by example before formalising the definition. The other key to its success is that exercises are provided along with the examples to make the concepts concrete.

There are however some gaps, which are not problematic for the reader, until you actually sit down to do the exercises. This blog post is intended as commentary should you get stuck working through that tutorial. I have included some documentation on monads which should help you avoid the red herrings that are thrown into introductory tutorials.

Please read the following after you have read You Could Have Invented Monads.

I will start by repeating the errors of those who have gone before me (explaining Monads by providing a formal definition) by introducing generalized notation. **The key to learning monads is interpreting type signatures.**

f and g are functions that map from some type to the same type, like Int to Int.

f, g :: a -> a

f', g' are analogues to f and g with the addition the the result is chucked into a container. The examples of containers in the tutorial are tuples (Integer, String), lists [a], and states (StdGen, a StdGen).

f', g' :: a -> m b

Next up is bind. bind f' combines two containers (m a and m b). So bind by itself combines two functions of type (a -> m b), f' and g'. This is where the type signatures are useful. The inputs are actually (a -> m b) and (m a), not (a -> m b) and (a -> m b). What gives? Well, bind combines f' and g' a. Either g' requires an argument, therefore giving a container with a value as the output, or we just add a container with a value as the input. The type signature shows the output of bind is also a container with a value in it.

bind f' :: m a -> m b

=> bind :: (a -> m b) -> m a -> m b

note: bind has been defined right associative in the tutorial so if's f (g x) or h (f (g x)), or bind h' . bind f' g' x.

unit is the identity analogue where f . id = id and id . f = id.

unit :: a - > m a

lift niftily converts a regular function with type (a -> a) to a monad (a -> m b).

lift f :: a -> m b

=> lift :: (a -> a) -> a -> m b

**A digression**

Having defined a bind function that connects a (a -> m b) function to a container/monad (m b), wouldn't another useful function be one that connects two (a -> m b) functions?

Enter the compose function (Thompson).

>@> :: (a -> m b) -> (b -> m c) -> (a -> m c)

The monad compose function is introduced during formal definitions of monads as it is easier to show associativity with this function, rather than bind. Associativity is one of the requirements to qualify as a monad.

Next, let's define a function that connects two containers.

It is a monadic sequencing operator which throws away the unpacked value of type a before executing the action of type m b (Yet Another Monad Tutorial - part 3).

>> :: (m a) -> (m b) -> (m b)

Allows for containers to be combined and throws away the inputs.

**The three exercises**

There are only three exercises for each Monad in the tutorial.

1) define bind. It has the type signature define earlier.

1b) define an operator * such that unit * f' = f' * unit = f'

note that:

f' :: a -> m b

also, the operator * is an infix equivalent of the function bind.

2) define unit. 2b) define lift as lift f = unit . f

3) show that lift f * lift g = lift (f . g)

note: equivalent to f'' * g'' where f'' = lift f and g'' = lift g

And that's it. Answers to follow in subsequent posts.

...

For the record, I tried Real World Haskell, Learn You a Haskell, and Write Yourself a Scheme. I also watched Brian Beckman's Don't Fear the Monad, which made sense at the time, but had forgotten soon after watching. In relation to other useful references, I found **this** to be a good companion piece that provides an intuitive explanation. Mike Vanier's series (I read 1, 2 and 3) is also useful too, but probably only after grasping most of it.

Why are Monads confusing? Because it is a very abstract concept that is best explained in a non-abstract way. Aside from that, notation and partial function application, mainly. I also think that it should be called containers for side effects, or something like that.