

Monad is not difficult - jmillikin
http://ianen.org/articles/monad-is-not-difficult/

======
jrockway
Honestly, I don't think your explanation is any easier to grasp than "All
about monads". I think RWH and the Typeclassopedia are easier for the
uninitiated to understand. ("You could have invented monads" is also very
good. Although I think it's sad that I know the exact titles of blog posts
about monads...)

What I like about RWH is that it builds up monads as "why you need this". You
see code in its non-monadic form for a while, and then monads are introduced,
and suddenly you see the same program being significantly smaller. You
understand the before and after, and can begin to reason for yourself what a
monad is. And it becomes abundantly clear why they are useful in Haskell --
you just saw your program shrink by 2/3s.

And a nitpick unrelated to your article -- I notice a lot of Haskell articles
implement things unnaturally just to use a certain feature. This makes it hard
to understand why you would actually _want_ to use that feature. The reader
skims the article, says "this is just a fold", and dismisses monads forever.
(I remember reading LYAH's section on applicative functors once. All the
examples do nothing, they are merely functions that technically type-check.
Not a good way to learn; the real paper on applicative functors is much more
approachable. But I digress.)

~~~
jmillikin
I agree, generally; it's a bit hard to write something better than RWH over a
lunch break. But sometimes, breaking down the same problem from multiple
viewpoints helps readers to understand what's going on.

My particular purpose in writing this is to demystify monads specifically,
especially for people who are casually interested in learning Haskell but
unwilling to read a few hundred pages on it. RWH is great, but it doesn't
explain monads until _chapter 14_ \-- that's a lot of material a reader has to
understand before they can even parse the examples.

~~~
jrockway
_But sometimes, breaking down the same problem from multiple viewpoints helps
readers to understand what's going on._

I think 43% of the confusion about monads is due to the sheer number of "monad
tutorials", each explaining two or three functions (return/bind,
pure/fmap/join) with different, overly-complex analogies. (A monad is like a
burrito, a monad is like a space suit, a monad is like a nuclear waste
container...)

The tutorials start with some analogy, and then inevitably explain how "the
list monad" and "the maybe monad" work. At the end you know that monads are
like burritos, how to apply a function to every value in a list, and how to
return failure from a function. But you still don't know anything about
monads, or more importantly _why_ monads.

If I were to write a monad tutorial, it would include these key points:

1) A monad is not a thing, it's a property of other things. Maybe is a thing.
A list is a thing. Both are monads. (My bike is a thing. My wall is a thing.
Both are blue.)

2) The abstract concept of a monad lets you reuse code. If you want to apply a
function to every value of a list, you could do that without monads. If you
want functions to be able to fail, and you want the failures to be composable,
you could do that without monads. But what you can't do without monads is
write a function like liftM2. With monads, you can turn a normal function into
one that works on lists. Or that works on IO. Or that works on computations
that can fail. You get to use the same function for all three types. That's
the point of monads.

(Then there will be a code example:

    
    
        2 + 3 --> 5
        liftM2 (+) (Just 2) (Just 3) --> Just 5
        liftM2 (+) Nothing (Just 3) --> Nothing
        liftM2 (+) (Just 2) Nothing --> Nothing
        liftM2 (+) [1,2] [3,4] --> [4,5,5,6]
        liftM2 (+) readLn readLn --> 1 <ENT> 2 <ENT> --> 3
    

Then it all makes sense!)

~~~
jmillikin
(note: HN mangles <*>, so I'm using <∗> instead

Isn't #2 a property of functors in general? I know I usually use <$> and <∗>
rather than the liftM family because they don't limit the number of
parameters.

    
    
      (+) <$> (Just 2) <∗> (Just 3)
      (+) <$> [1,2] <∗> [3,4]
      (+) <$> readLn <∗> readLn

~~~
ch
Does this mean that you could go on an say:

    
    
        (+) <$> (Just 2) <∗> (Just 3) <∗> (Just 5)
    

And it would have the same meaning as:

    
    
        liftM3 (+) (Just 2) (Just 3) (Just 5)
    
    

_edited for formatting_

~~~
jmillikin
Exactly. You can use the applicative operators on functions with an arbitrary
number of parameters.

Note, though, that (+) only takes two parameters, so your examples won't work
as written. These should be equivalent:

    
    
      enumFromThenTo <$> Just 2 <*> Just 3 <*> Just 5
      liftM3 enumFromThenTo (Just 2) (Just 3) (Just 5)

~~~
ch
Neat. I did see that liftM3 takes a function of 3 arguments, and just plain
ignored that fact in my example :)

And to be clear, for <$> and <*>, you need a Functor instance defined for you
type right?

Are there benefits to using one or the other, they seem to evaluate the same,
is GHC able to optimize Monad and Functor equally?

~~~
jmillikin
Right -- liftM and friends are for monads, <$> and <∗> are for functors. All
monads are _supposed_ to be functors, though there's currently no type-level
guarantee for historical reasons. Most instances of Monad also provide an
instance of Functor.

    
    
      Are there benefits to using one or the other, they seem to evaluate the same, is GHC able to optimize Monad and Functor equally?
    

I believe there's currently no special optimizations for either case, though
as I don't poke around in GHC this statement may be mistaken.

The primary advantage of the application operators over liftM is that there's
no liftM6, liftM7, etc; you can type <∗> as much as you want.

~~~
jrockway
In Haskell, <∗> is implemented in "Applicative", not "Functor". So a Functor
instance is not enough. <$> is from Functor, however.

~~~
jmillikin
Oh, that's right -- I forgot applicatives are a separate class.

Regardless, the concept of "lifting" pure functions is separate from monads,
which exist to enforce sequencing.

------
jmillikin
This is an extension of my comment at <
<http://news.ycombinator.com/item?id=1144481> > \-- it was so well received
that I decided to write up a proper article.

There's something about the word "monad" that just scares the hell out of
people, but hopefully approaching monads from a more practical and less
mathematical standpoint will make grasping them easier. They're really not
that complicated.

------
FlemishBeeCycle
When I was figuring out what a monad was the biggest impediments were:

1) Superfluous analogies

2) Usage of do-syntax rather than bind and return.

Do-syntax, which sweeps the best example of how a monad _actually_ works under
the rug, used in conjunction with the phrase "inside a monad", can cause
beginners over-complicate and mysticize the idea of a monad.

I have not yet read the above tutorial, but the best one I have seen to date
is <http://ertes.de/articles/monads.html>

~~~
jmillikin
That's an excellent link; I've added it to the introduction.

------
jerf
I think the best way of looking at monads for most programmers is the one
described in [http://blog.sigfpe.com/2010/01/monads-are-trees-with-
graftin...](http://blog.sigfpe.com/2010/01/monads-are-trees-with-
grafting.html) (which links to the actual PDF
<https://dl.dropbox.com/u/828035/Monads/monads.pdf> ).

------
Zak
This site causes a tab crash on Chrome 5.0.307.9 beta running on x64 Linux.

~~~
jmillikin
Sorry about that :(

It's valid markup[1], and doesn't use any weird plugins. You may want to
report the crash to the Chrome team.

[1]
[http://validator.w3.org/check?uri=http%3A%2F%2Fianen.org%2Fa...](http://validator.w3.org/check?uri=http%3A%2F%2Fianen.org%2Farticles%2Fmonad-
is-not-difficult%2F&charset=%28detect+automatically%29&doctype=Inline&group=0)

~~~
Zak
I did, using a web form I found that required that I tell it what version of
Windows I'm using and upload a log file that doesn't seem to exist on the
Linux version.

It's an interesting enough article to open another browser though.

------
trezor
I'm pretty sure if someone would try to explain Monads without actually using
Haskell syntax it might actually be possible to understand. This explained
nothing.

Haskell advocates mention pure code and monads as pros of Haskell and typical
Haskell conventions. But I'm simply not willing to learn a language's full
syntax to learn about some generic computing concept and how it is employed in
a specific language.

If I need to learn the language you are trying to sell me to understand the
concept your are trying to explain me in order to sell me the language, don't
expect to get very far.

