A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
In functional programming, a monad is a software design pattern with a structure that combines program fragments (functions) and wraps their return values in a type with additional computation.
The term monad (from Ancient Greek μονάς (monas) 'unity', and μόνος (monos) 'alone') is used in some cosmic philosophy and cosmogony to refer to a most basic or original substance. As originally conceived by the Pythagoreans, the Monad is the Supreme Being, divinity or the totality of all things.
So in simple words, a monad is a rule to pass from any type X to another type T(X) , and a rule to pass from two functions f:X->T(Y) and g:Y->T(Z) (that you would like to compose but can't) to a new function h:X->T(Z) . Which, however, is not the composition in strict mathematical sense.
Yes, there are several things outside programming that can be said to be like monads. No, none of them will help you understand monads. Please read Abstraction, intuition, and the “monad tutorial fallacy”:
Joe Haskeller is trying to learn about monads. After struggling to understand them for a week, looking at examples, writing code, reading things other people have written, he finally has an “aha!” moment: everything is suddenly clear, and Joe Understands Monads! What has really happened, of course, is that Joe’s brain has fit all the details together into a higher-level abstraction, a metaphor which Joe can use to get an intuitive grasp of monads; let us suppose that Joe’s metaphor is that Monads are Like Burritos. Here is where Joe badly misinterprets his own thought process: “Of course!” Joe thinks. “It’s all so simple now. The key to understanding monads is that they are Like Burritos. If only I had thought of this before!” The problem, of course, is that if Joe HAD thought of this before, it wouldn’t have helped: the week of struggling through details was a necessary and integral part of forming Joe’s Burrito intuition, not a sad consequence of his failure to hit upon the idea sooner.
But now Joe goes and writes a monad tutorial called “Monads are Burritos,” under the well-intentioned but mistaken assumption that if other people read his magical insight, learning about monads will be a snap for them. “Monads are easy,” Joe writes. “Think of them as burritos.” Joe hides all the actual details about types and such because those are scary, and people will learn better if they can avoid all that difficult and confusing stuff. Of course, exactly the opposite is true, and all Joe has done is make it harder for people to learn about monads, because now they have to spend a week thinking that monads are burritos and getting utterly confused, and then a week trying to forget about the burrito analogy, before they can actually get down to the business of learning about monads.
As I said in another answer long ago, sigfpe's article You Could Have Invented Monads! (And Maybe You Already Have.), as well as Philip Wadler's original paper Monads for functional programming, are both excellent introductions (which give not analogies but lots of examples), but beyond that you just keep coding, and eventually it will all seem trivial.
[Not a real answer: One place monads exist outside all programming, of course, is in mathematics. As this hilarious post points out, "a monad is a monoid in the category of endofunctors, what's the problem?" :-)]
Edit: The questioner seems to have interpreted this answer as condescending, saying something like "Monads are so complicated they are beyond analogy". In fact, nothing of the sort was intended, and it's monad-analogies that often appear condescending. Maybe I should restate my point as "You don't have to understand monads". You use particular monads because they're useful — you use the Maybe monad when you need Maybe types, you use the IO monad when you need to do IO, similarly other examples, and apparently in C#, you use the Nullable<> pattern, LINQ and query comprehensions, etc. Now, the insight that there's a single general abstraction underlying all these structures, which we call a monad, is not necessary to understand or use the specific monads. It is something that can come as an afterthought, after you've seen more than one example and recognise a pattern: learning proceeds from the concrete to the abstract. Directly explaining the abstraction, by appealing to analogies of the abstraction itself, does not usually help a learner grasp what it's an abstraction of.
Here's my current stab at it:
Monads are bucket brigades:
>>=
, operation).return
operation is simply the operation of putting stuff in the bucket.>>
) operations, the contents of the bucket are dumped before they're passed to the next person. The next person doesn't care what was in the bucket, they're just waiting to receive it.()
, a ticket is being passed around inside the bucket. It's called "the Unit", and it's just a blank sheet of paper.Hope this helps. :-)
Edit: I appreciate your support, but sadly, the Monad Tutorial curse has struck again. What I've described is just function application with containers, not monads! But I'm no nihilist – I believe the Monad Tutorial curse can be broken! So here's a somewhat more, um, complicated picture that I think describes it a bit better. You decide whether it's worth taking to your friends.
Monads are a bucket brigade with project managers. The project managers stand behind all but the first member of the brigade. The members of the bucket brigade are seated on stools, and have buckets in front of them.
The first person receives some stuff, does something with it, and puts it in a bucket. That person then hands off – not to the next person in the brigade, that would be too easy! :-) – but to the project manager standing behind that person.
The project manager (her name is bind, or >>=
) takes the bucket and decides what to do with it. She may decide to take the first person's stuff out of the bucket and just hand it to the person in front of her without further ado (that's the IO monad). She may choose to throw the bucket away and end the brigade (that's fail
). She may decide to just bypass the person in front of her and pass the bucket to the next manager in the brigade without further ado (that's what happens with Nothing
in the Maybe
monad). She may even decide to take the stuff out of the bucket and hand it to the person in front of her a piece at a time! (That's the List monad.) In the case of sequence (>>
) she just taps the shoulder of the person in front of her, instead of handing them any stuff.
When the next person makes a bucket of stuff, the person hands it to the next project manager. The next project manager figures out again what to do with the bucket she's given, and hands the stuff in the bucket to her person. At the end, the bucket is passed back up the chain of project managers, who can optionally do stuff with the bucket (like the List
monad assembling all the results). The first project manager produces a bucket of stuff as the result.
In the case of the do
syntax, each person is actually an operation that's defined on the spot within the context of everything that's gone before – as if the project manager passes along not just what's in the bucket, but also the values (er, stuff) that have been generated by the previous members of the brigade. The context building in this case is much easier to see if you write out the computation using bind and sequence instead of using the do
syntax – note each successive "statement" is an anonymous function constructed within the operation that's preceded that point.
() values, IO monads, and the return
operation remain described as above.
"But this is too complicated! Why can't the people just unload the buckets themselves?" I hear you ask. Well, the project manager can do a bunch of work behind the scenes that would otherwise complicate the person's work. We're trying to make it easy on these brigade members, so they don't have to do too much. In the case of the Maybe monad, for example, each person doesn't have to check the value of what they're given to see if they were given Nothing – the project manager takes care of that for them.
"Well, then, if you're realliy trying to make each person's job easier, why not go all the way – have a person just take stuff and hand off stuff, and let the project manager worry about the bucketing?" That's often done, and it has a special name called lifting the person (er, operation) into the monad. Sometimes, though, you want a person that has something a bit more complicated to do, where they want some control over the bucket that's produced (e.g. whether they need to return Nothing
in the case of the Maybe
monad), and that's what the monad in full generality provides.
The points being:
Thus ends my bedtime tutorial. :-P
In non-programming terms:
If F and G are a pair of adjoint functors, with F left adjoint to G, then the composition G.F is a monad.
Is there some concept/thing outside of programming (outside of all programming, not just FP) which could be said to act or be monad-like in a significant way?
Yes, in fact there is. Monads are quite directly related to "possibility" in modal logic by an extension of the Curry-Howard isomorphism. (See: A Judgmental Reconstruction of Modal Logic.)
This is quite a strong relationship, and to me the concepts related to possibility on the logical side are more intuitive than those related to monads from category theory. The best way I've found to explain monads to my students draws on this relationship but without explicitly showing the isomorphism.
The basic idea is that without monads, all expressions exist in the same world, and all calculation is done in that world. But with monads there can be many worlds and the calculation moves between them. (e.g., each world might specify the current value of some mutable state)
In this view, a monad p
means "in a possible reachable world from the current world".
In particular if t
is a type then:
x :: t
means something of type t is directly available in the current worldy :: p t
means something of type t is available in a world reachable from the current one
Then, return
allows us to use the current world as a reachable one.
return :: t -> p t
And >>=
allows us to make use of a something in a reachable world and then to reach additional worlds from that world.
(>>=) :: p t -> (t -> p s) -> p s
So >>=
can be used to construct a path to a reachable world from smaller paths through other worlds.
With the worlds being something like states this is pretty easy to explain. For something like an IO monad, it's also pretty easy: a world is specified by all the interactions a program has had with the outside world.
For non-termination two worlds suffice - the ordinary one, and one that is infinitely far in the future. (Applying >>= with the second world is allowed, but you're unlikely to observe what happens in that world.) For a continuation monad, the world remains the same when continuations are used normally, and there are extra worlds for when they are not (e.g., for callcc).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With