I think I understand what 'Maybe Monads' are, but I'm not sure about the other types.
The easiest way to grok them (at least for me) is as "decorators", adding behavior while preserving the underlying semantics. Or, an even dirtier definition: it's functional programming's operator overloading.
But, You could have invented Monads!
sigfpe says:
But all of these introduce monads as something esoteric in need of explanation. But what I want to argue is that they aren't esoteric at all. In fact, faced with various problems in functional programming you would have been led, inexorably, to certain solutions, all of which are examples of monads. In fact, I hope to get you to invent them now if you haven't already. It's then a small step to notice that all of these solutions are in fact the same solution in disguise. And after reading this, you might be in a better position to understand other documents on monads because you'll recognise everything you see as something you've already invented.
Many of the problems that monads try to solve are related to the issue of side effects. So we'll start with them. (Note that monads let you do more than handle side-effects, in particular many types of container object can be viewed as monads. Some of the introductions to monads find it hard to reconcile these two different uses of monads and concentrate on just one or the other.)
In an imperative programming language such as C++, functions behave nothing like the functions of mathematics. For example, suppose we have a C++ function that takes a single floating point argument and returns a floating point result. Superficially it might seem a little like a mathematical function mapping reals to reals, but a C++ function can do more than just return a number that depends on its arguments. It can read and write the values of global variables as well as writing output to the screen and receiving input from the user. In a pure functional language, however, a function can only read what is supplied to it in its arguments and the only way it can have an effect on the world is through the values it returns.
My favorite Monad tutorial:
http://www.haskell.org/all_about_monads/html/index.html
(out of 170,000 hits on a Google search for "monad tutorial"!)
@Stu: The point of monads is to allow you to add (usually) sequential semantics to otherwise pure code; you can even compose monads (using Monad Transformers) and get more interesting and complicated combined semantics, like parsing with error handling, shared state, and logging, for example. All of this is possible in pure code, monads just allow you to abstract it away and reuse it in modular libraries (always good in programming), as well as providing convenient syntax to make it look imperative.
Haskell already has operator overloading[1]: it uses type classes much the way one might use interfaces in Java or C# but Haskell just happens to also allow non-alphanumeric tokens like + && and > as infix identifiers. It's only operator overloading in your way of looking at it if you mean "overloading the semicolon" [2]. It sounds like black magic and asking for trouble to "overload the semicolon" (picture enterprising Perl hackers getting wind of this idea) but the point is that without monads there is no semicolon, since purely functional code does not require or allow explicit sequencing.
This all sounds much more complicated than it needs to. sigfpe's article is pretty cool but uses Haskell to explain it, which sort of fails to break the chicken and egg problem of understanding Haskell to grok Monads and understanding Monads to grok Haskell.
[1] This is a separate issue from monads but monads use Haskell's operator overloading feature.
[2] This is also an oversimplification since the operator for chaining monadic actions is >>= (pronounced "bind") but there is syntactic sugar ("do") that lets you use braces and semicolons and/or indentation and newlines.
This video is one of the clearest and most concise explanation of monads that I have come across:
A monad is, effectively, a form of "type operator". It will do three things. First it will "wrap" ( or otherwise convert) a value of one type into another type (typically called a "monadic type"). Secondly it will make all the operations ( or functions ) available on the underlying type available on the monadic type. Finally it will provide support for combining its self with another monad to produce a composite monad.
The "maybe monad" is essentially the equivalent of "nullable types" in VB / C#. It takes a non nullable type "T" and converts it into a "Nullable<T>", and then defines what all the binary operators mean on a Nullable<T>.
Side effects are represented simillarly. A structure is created that holds descriptions of side effects along side a function's return value. The "lifted" operations then copy around side effects as values are passed between functions.
The are called "monads" rather than the easier to grasp name of "type operators" for several reasons:
- Monads have restrictions on what they can do (see the definiton for details).
- Those restrictions, along with the fact that there are 3 operations involved, conform to the structure of something called a monad in Category Theory, which is an obscure branch of mathematics.
- They were designed by proponents of "pure" functional languages
- Proponents of pure functional languages like obscure branches of mathematics
- Because the math is obscure, and monads are associated with particular styles of programming, people tend to use the word monad as a sort of secret handshake. Because of this no one has bothered to invest in a better name.
The two things that helped me best when learning about there were:
Chapter 8, "Functional Parsers," from Graham Hutton's book Programming in Haskell. This doesn't mention monads at all, actually, but if you can work through chapter and really understand everything in it, particularly how a sequence of bind operations is evaluated, you'll understand the internals of monads. Expect this to take several tries.
The tutorial All About Monads. This gives several good examples of their use, and I have to say that the analogy in Appendex I worked for me.
Two little tutorials from the wikibooks to explain the idea (one is F# but provides a nice short definition):
Princess's explanation of F# Computation Expressions helped me, though I still can't say I've really understood.
http://code.google.com/p/monad-tutorial/ is a Work In Progress to address exactly this question.
A monad is a way of combining computations together that share a common context. It is like building a network of pipes. When constructing the network, there is no data flowing through it. But when I have finished piecing all the bits together with 'bind' and 'return' then I invoke something like runMyMonad monad data
and the data flows through the pipes.
As soon as you understand Monads, you will understand that this is a Monad, too.
xkcd:248 Hypotheticals
{{alt: What if someone broke out of a hypothetical situation in your room right now?}}