- Don't read the monad tutorials.
- No really, don't read the monad tutorials.
- Learn about Haskell types.
- Learn what a typeclass is.
- Read the Typeclassopedia.
- Read the monad definitions.
- Use monads in real code.
- Don't write monad-analogy tutorials.
http://dev.stephendiehl.com/hask/#monadsWithout yet really understanding monads, I've come to realize that their only real problem is the name -- being named after some rather obscure (for most!) category theory concept -- that itself seems just about as simple and trivial as monads are. I find they are a little like the y-combinator in that regard.
I'm not sure if what we need is category theory in elementary school, or a different framework for discussing monads as it relates to programming -- but I'm almost convinced the confusion has to do with the language used to describe them.
Programming is a very practical art that sits on top of the much more abstract art of mathematics. It's useful to know orders of magnitude, graph theory, statistics, logic... but the art by which these concepts are animated and put to use is rather prosaic. And the discipline of computing has forged a set of concepts that are "appropriately abstract" (much, I think due to Knuth) -- but monads seem to lie just outside the grasp of many programmers. And I don't think it is because they are a particularly intrinsically hard concept.
There are excellent explanations of monads for JavaScript, F#, Clojure and Erlang, to name a few. Pick one of them, for the language you're most familiar with. Avoid any syntactic sugar in the beginning. Avoid reading about Maybe/Option monad - it's too boring. Start with hand-crafted List monad, then go to State and/or Promise/Deferred monads, and then ignore State, Either, Writer and many more monads, which are either boring or only relevant in pure languages. Then start sugaring the syntax, `for` in Scala and "computational expressions" in F# are good for this, also LiveScript back-calls are passable. If you're into Lisps, then of course you have macros and it's a good exercise to write you own macros (of course, every Lisp out-there has many implementations already available to look at, if you're stuck).
At this point you know enough to get back to Haskell and/or to look at monad transformers and Cont monad. You can also read about monadic laws and actually have an idea what they are about.
It worked for me. I think the key to my method was to avoid reading about boring and/or not directly applicable things while constantly playing in a REPL with the interesting ones. I find it unbearable to learn theory of things I can't imagine being used. Once I use the "thing" a couple of times it changes and I can absorb theory pretty quickly.
That's because on this site the m-word is banned. Which is very, very good move in my opinion, but anyway: the "Railway oriented programming" is an article about monads and begins with a definition of Maybe/Option, it's just not explicitly named as such. It's also a very good tutorial, maybe even one of the best I read. I strongly recommend it, too.
Here is a list I found useful to learn more about monads (they aren't necessarily all the ones that I had to read to understand them, there was another page that I can't find right now): http://pauillac.inria.fr/~xleroy/mpri/2-4/monads.2up.pdf http://blog.enfranchisedmind.com/2007/08/a-monad-tutorial-fo... http://ambassadortothecomputers.blogspot.ro/2009/02/equeue-c... http://blog.0branch.com/posts/2012-03-26-01-implementing-fun... http://blog.0branch.com/posts/2012-03-26-02-from-functor.htm...
http://research.microsoft.com/en-us/um/people/simonpj/papers...
The TLDR: Haskell uses lazy evaluation, meaning expressions are evaluated in an umpredictable order. If expression evaluation had side effects, programs would become unmanageable, so in Haskell, al computations must be pure. Monads are a neat trick where you use a specially crafted abstract (opaque) interface that lets you model side-effecting computations, specifying what order things should run in.
Of course, initially the biggest reason for using monads so prominently is the IO but the monad interface is much more general and an also be used for other things (List, Maybe, etc)