[Haskell-beginners] Re: Thinking about monads

Michael Mossey mpm at alumni.caltech.edu
Sun Apr 12 17:02:40 EDT 2009

Ertugrul Soeylemez wrote:
> Michael Mossey <mpm at alumni.caltech.edu> wrote:
>> I'm getting a better grasp on monads, I think. My original problem, I
>> think, was that I was still thinking imperatively. So when I saw this:
>> class Monad m where
>>     (>>=) :: m a -> (a -> m b) -> m b
>> I didn't understand the "big deal". I thought, okay so you "do" something with the 
>> function (a -> m b) and you "arrive" at m b.  [...]
> Think of f being a computation, in which something is missing.  It takes
> this something through a parameter.  So f is actually a function, which
> takes a value and results in a computation.  Another intuition:  f is a
> parametric computation.  Now if c0 is a computation, then
>   c0 >>= f
> is another computation built by feeding the result of c0 to f.  More
> graphically you've plugged the result cable of c0 to the input port of
> f.
> As a real world example, consider a computation, which prints a value x:
>   print x
> That x has to come from somewhere, so this should actually be a function
> of some value x:
>   \x -> print x
> If that x should come from another computation, then (>>=) comes into
> play.  You can pass the result of one computation to the above one.  For
> example, if x comes from the result of getChar, you can write:
>   getChar >>= \x -> print x
> or simply:
>   getChar >>= print

Well, here are my thoughts. I know what you write is the way monads are introduced in 
most of the texts I've seen, but to the eyes of an imperative programmer, nothing 
"special" is going on. Let's give an example (but replace getChar by something 
deterministic). When I see

thing1 >>= thing2

I think to myself, this is basically the same as:

(Example A)
f input = result'
   where result = thing1 input
         result' = thing2 result

But it's not the same, because certain problems arise. What's special about monads is 
the way they are used and the particular problem they are trying to solve. For 
example, here are some problems we need to solve:

(1) how do you pass state from one function to the next in the most elegant way 
(avoiding the need to make complicated data types and having the ability to hide 
implementation details)

(2) how do you deal with errors? how do you "return early" from a set of computations 
that have hit a wall?

I confess I have not read any chapters on monads themselves, but I have finished 
Chapter 10 of Real World Haskell, which is mostly about motivating monads and 
implementing something very close to them. They use an operator they call ==>, which 
is nearly identical to >>=.

I see one answer to (1). Something like

(Example B)
f input =
    thing1 input >>= \result ->
    thing2 result >>= \result' ->
    return (result, result')

separates the idea of the state we passing "down the chain" from the results we get. 
I'll rewrite example (A) above, to be more explicit about what we are trying to do:

(Example C)
f state = (result, result')
   where (result, state')   = thing1 state
         (result', state'') = thing2 result state'

In example (B), the results are naturally available because they are arguments to 
functions, and all functions further down the chain are nested within them.

Now about problem (2)? The way the >>= operator is defined, it allows 
"short-circuiting" any remaining functions after we get a bad result. If the state is 
Maybe or Either, we can define >>= such that a result of Nothing or Left causes all 
remaining functions to be skipped. We could do this without monads, but it would look 
very ugly.

As a beginner, I'm not trying to lecture anyone, but putting down my thoughts so I 
can get feedback. I feel there's no way to "understand" monads without understanding 
the motivation of the problem we are trying to solve, or without seeing specific 
implementations. Chapter 10 of Real World Haskell provides a lot of motivation by 
showing early awkward attempts to solve these problems.


More information about the Beginners mailing list