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.)
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.
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.
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.
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.
Agreed. Clear, real examples of abstract ideas are really important, and applies to much more than just monads. RWH's monads stuff (in particular its parsec chapter) is a good example of a concept in action, and its easy to see why you would actually use that model.
Some 'first principles' things are difficult to present like this because there are usually better ways to do it. The state monad is like this. Even in haskell there are more expressive (and easier to use) tools to do the same thing. In this case i think we can all accept somewhat ad hoc examples as long as they are disclaimed.
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.
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 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.
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.
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.)