A nice tutorial. By the way, Monads are an interesting pattern. But far from the only type class that useful in Haskell. The Typeclassopidea (in http://www.haskell.org/sitewiki/images/8/85/TMR-Issue13.pdf) gives a nice overview. I find Arrows especially interesting at the moment, but that probably because I already know Monads, Functors and pointed Functors quite well.
Conal Elliott has an interesting blog post talking showing how to use Arrows as semantic editor combinators (http://conal.net/blog/posts/semantic-editor-combinators/). It's enough to get you started on arrows with a useful application. (Of course, as with Monads, arrows are much more than this one application. But seeing one concrete application is a good start for your imagination.)
You can think of Arrows as generalised functions: the type of a function is X -> Y, whilst the type of an arrow is A X Y, where A takes the place of the infix type ->. So another way you can write the type of a function is (->) X Y, from this (+ technicalities) we see that functions are Arrows.
Monads are a special case of arrows where A X Y becomes X -> M Y or (without the infix syntactic sugar) (->) X (M Y); Monads can take control of the outputs from operations, whilst Arrows can take control of both the input and output to operations.
I found Monads made a lot more sense after I learnt about Arrows because Arrows are what I wanted Monads to be.
Yes. And Monads are also a special case of Functors (and of Pointed Functors). Interestingly, Functors and Arrows are different generalizations of Monads, and neither is a generalization of the other.
I also agree with Parsec being the killer application of Monads. In a purely functional setting Input/Output and similar things suffice as a motivation for monads, but that won't excite any Java programmer. But using Monads for a parser, like Parsec does, would also be a good idea in Java.
I've read several monad tutorials and read countless comments describing their uses, and I have not understood their advantages until reading this article. I'll fess up to my part of the problem: I never wrote any after reading these tutorials, but I wouldn't have known what to try. I knew they are an abstraction for computation (what isn't?), and they let you do things like safe division and LINQ, and they're like a burrito (what isn't?), but I could never look at code and say, "Obviously this needs a monad!" Demonstrating how monads introduce context, after showing what you mean by context and why it's useful, is a very helpful approach. Pronouns were a nice analogy. I don't fully grok monads yet, but now I'll look at code and decide that it might be nicer if I introduce a context
"We will be treating monads as a design pattern instead of monoids in the category of endofunctors. The latter perspective is interesting to the people who like to design languages; the former perspective is interesting to people who like to write code." That kind of perspective is really important but I have to say that one rarely hears it from the academic community. To my knowledge providing perspective is supposed to be part of their job description.
Conal Elliott has an interesting blog post talking showing how to use Arrows as semantic editor combinators (http://conal.net/blog/posts/semantic-editor-combinators/). It's enough to get you started on arrows with a useful application. (Of course, as with Monads, arrows are much more than this one application. But seeing one concrete application is a good start for your imagination.)