I've been trying to find idiomatic ways of explaining monads to people who already know how to program, but may not be using functional languages. Possibly this explanation will be useful. I would be happy for some criticism.

A monad is a type of functor. In terms of programming a functor is a collection: a data structure that can hold a piece of information. Functors have a function related to them, usually called "map" or "fmap" (for 'functor map'). "map" takes the information out of the collection, transforms it with a function that you pass to "map" and then puts it back in to the same kind of collection. Most programmers have experience with this if they use a modern programming language (though they may not have known it was a "functor" that they were using).

Quick note: I always found the word "functor" to be confusing because it sounds like it should do something rather than be something. This is true in category theory where the concept originates, but the computer programming implementation turns out differently. I'm going to try to avoid category theory in this explanation, but it's still interesting to look into.

Like I said, a monad is just a special type of functor. With a functor, it is possible to change the type of the information you are working on with the function you pass to "map". You might have a function that converts an character to an integer (maybe just giving its ASCII representation). Then you can pass that function to map and your collection of characters will be converted to a collection of integers. Monads (used as monads) don't allow this.

Monads use a function called "bind". It works a bit like "map" except that the function you pass to "bind" needs to return the resultant monad rather than just the transformed information. For example, if you have a container that contains an integer, you need to pass a function to "bind" that returns a container that contains an integer. You can transform the integer in the function, but you must always return a container with the integer inside.

Why do you want a monad? It is so you can chain actions knowing that bind will always return the exact same type. A place where I often build monads is in refining a search. I start with a collection of data. I call "bind" with the refinement function. This will return a collection of data. I call "bind" with the next refinement function. I just keep doing that until I've finished the refinement and I'm left with the refined collection of data. I can always add more refinements to the chain because I know that "bind" will always return a container of search results.

Implementation detail: You might be wondering why "bind" has to return a monad, while "map" just returns the transformed data (after which "map" puts it back into the functor). "map"'s behaviour seems much more convenient. The reason is so you can handle data structures that have optional data. Imagine our monad can contain either search results or an error. If the monad returns search results, "bind" will call the function passed to it. Otherwise it will just return the monad containing the error. This allows you to return a monad containing an error from your function. If you were using "map", there is no way to return that error.

And that's basically it. Collections are almost always functors meaning that you can define map on them. You use map to apply general transformations on the data in the collection. Most functors can also be monads which means you can implement bind on them. You use bind to successively apply operations on a data structure, always getting the exact same type of data structure back. bind forces the function passed it it to return a monad, which allows you to store optional information in the monad.

Final aside: I think that monads are as important in OO as they are in FP, IMHO. In fact, an object itself is a monad: Write a method on an object that does a transformation of the data in the object and returns a new object of the same type with the transformed data. In this case, the application of the method (usually "." in most programming languages) is "bind" and the method is the function that you passed to bind. However, I'll warn you that if you are implementing monads this way, avoid subclass polymorphism unless you want to go crazy ;-)

Edit: spelling