views:

935

answers:

11

How would you describe a monad in non-programming terms? 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?

+1  A: 

I like to think of them as abstractions of computations that can be "bound." Or, burritos!

J Cooper
A: 

Try this link

peterwkc
+11  A: 

Here's my current stab at it:

Monads are bucket brigades:

  1. Each operation is a person standing in line; i.e. there's an unambiguous sequence in which the operations take place.
  2. Each person takes one bucket as input, takes stuff out of it, and puts new stuff in the bucket. The bucket, in turn, is passed down to the next person in the brigade (through the bind, or >>=, operation).
  3. The return operation is simply the operation of putting stuff in the bucket.
  4. In the case of sequence (>>) 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.
  5. In the case of monads on (), a ticket is being passed around inside the bucket. It's called "the Unit", and it's just a blank sheet of paper.
  6. In the case of IO monads, each person says something aloud that's either utterly profound or utterly stupid – but they can only speak when they're holding the bucket.

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:

  1. The operations are sequenced.
  2. Each person knows how to make buckets, but not how to get stuff out of buckets.
  3. Each project manager knows how to deal with buckets, and how to get stuff out of them, but doesn't care what's in them.

Thus ends my bedtime tutorial. :-P

Owen S.
So, how would using this analogy make it easier to describe, say, the `State` monad's `get` and `put` operations? Or, perhaps, the `Cont` monad and `callCC`?
camccann
It doesn't – get, put, and callCC are not operations pertaining to the monad itself. This analogy is for getting the Monad class under one's fingers alone, and focuses on the bind and sequencing operations that are at the core of every monad.
Owen S.
Just to make sure you're annoyed, though: MonadState has its own analogy. There's no buckets in this case, but there is a state which is invisibly passed along the bucket brigade. Get is a person that copies the state (conceptually), and passes the copy of the state along. Put replaces the state with whatever he receives and hands off an empty piece of paper. Everyone else ignores the state, and only deals with what they're handed, which is the key part. runState sets up the whole thing and returns the final state along with the final value.
Owen S.
Good work. Writing monad tutorials after you've understood them seems to be part of the learning experience, but I still think they help the writer more than the new-to-monads learner. :-)
ShreevatsaR
Yes, and that's one of the problems with analogies--a monad by itself isn't really useful for much of anything. You use `State` because of `get` and `put`, not `>>=`. The crux of the matter is why the definition of a monad makes `get` and `put` possible, which most analogies don't help with *at all* because they only make sense for a couple specific monads at most, and almost always fail when applied to monads involving function types.
camccann
Not that there's anything wrong with your analogies--they're fine. It's just that, as always, it's very unlikely they'll do any good for anyone who doesn't already grasp the concepts.
camccann
@ShreevatsaR: They certainly do help the writer; even now my brain is picking apart my revision. :-)
Owen S.
@camccann: I subscribe that quite a bit of Haskell programming can be accomplished with Maybe, List, IO, and Either monads, and a great deal of perfectly fine Haskell can be spun out without ever touching MonadCont. :-) Yes, I agree, by the time you get to State, Cont, and transformers, you're past the analogy stage, and need to actually see how the computations are set up. No wait, now the bucket brigade are returning black boxes! ;-)
Owen S.
+2  A: 

Well, here's a nicely detailed description of monads that's definitely outside of all programming. I know it's outside of programming because I'm a programmer and I don't understand even half of what it talks about.

There's also a series of videos on YouTube explaining monads of that variety--here's the first in the sequence.

I'm guessing that's not really what you were looking for, though...

camccann
Actually, category theory has a lot to do with programming. In the sense that cosmology has to do with astronomy.
Apocalisp
+23  A: 

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.

ShreevatsaR
It's an unfortunate situation. I wonder if [this guy](http://wadler.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html) ever found the monad tutorial he asked for?
camccann
+1. Mike Vanier [makes this claim](http://mvanier.livejournal.com/1205.html) too.
Nikhil Chelliah
"Lame"? No. Any abstract concept may be learned through looking at various special cases (examples) and generalising, but rarely through analogies (which are usually imperfect and at best can make it less forbidding, not help with understanding). *After* you understand what monads are, you'll be able to come up with loads of analogies — and the exercise may even help you — but there's no evidence any of the zillions of monad-by-analogy tutorials ever helped anyone understand them in the first place. :-)
ShreevatsaR
(I tried to extract the smallest amount sufficient to get the point across.) There's nothing special about monads; the same is true of every abstraction. Monads aren't all that complicated really; just look at the examples, understand the monads you care about, get beyond the scary name and start coding, and one day the general idea will click. See the [timeline of monad tutorials](http://www.haskell.org/haskellwiki/Monad_tutorials_timeline) for a very small subset of the endless number of monad tutorials that have been written, with all manner of analogies. They don't help so much!
ShreevatsaR
@fig-gnuton: Or perhaps Haskellers who *speak from experience* that focusing on analogies **makes it harder to actually understand**. A non-answer is being voted up because your question is misguided. Why not read [this answer](http://stackoverflow.com/questions/2704652/2704795#2704795) again, because you're probably not going to get any better explanation than that one, and certainly not from "real-world" analogies.
camccann
A related quote from Ralph B. Boas, [ *Can We Make Mathematics Intelligible?* ](http://www.jstor.org/stable/2321471): "Suppose you want to teach the 'cat' concept to a very young child. Do you explain that a cat is a relatively small, primarily carnivorous mammal with retractable claws, a distinctive sonic output, etc.? I'll bet not. You probably show the kid a lot of different cats saying 'kitty' each time until it gets the idea. To put it more generally, generalizations are best made by abstraction from experience."
ShreevatsaR
+4  A: 

In practice, most of the monads I've worked with behave like some kind of implicit context.

It's like when you and a friend are trying to have a conversation about a mutual friend. Every time you say "Bob," you're both referring to the same Bob, and that fact is just implicitly threaded through your conversation due to the context of Bob being your mutual friend.

You can, of course, have a conversation with your boss (not your friend) about your skip-level manager (not your friend) who happens to be named Bob. Here you can have another conversation, again with some implied connotation that only makes sense within the context of the conversation. You can even utter the exact same words as you did with your friend, but they will carry a different meaning because of the different context.

In programming it's the same. The way that tell behaves depends on which monad you're in; the way that information is assembled (>>=) depends on which monad you're in. Same idea, different mode of conversation.

Heck, even the rules of the conversation can be monadic. "Don't tell anyone what I told you" hides information the same way that runST prevents references from escaping the ST monad. Obviously, conversations can have layers and layers of context, just like we have stacks of monad transformers.

Hope that helps.

intoverflow
Right - the implicit context is basically what I called a "possible reachable world" in my answer. One thing though: comonads also involve implicit contexts and your explanation seems to fit them as well as monads (except for mentioning >>= and runST). Maybe to be more precise it should be a bit more specific about how changes in context occur.
RD1
+9  A: 

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.

Mau
+1: for another "aha" moment
Alexandre C.
Did you just copy [the sentence](http://en.wikipedia.org/wiki/Monad_%28category_theory%29#Introduction) from Wikipedia? :-) Actually, the functional programming monads [apparently correspond to *strong monads*](http://en.wikipedia.org/wiki/Monads_in_functional_programming#Background) in mathematics.
ShreevatsaR
That's not helping; you just shifted from programming to (probably) math terms...
RCIX
RCIX: What terms would you like? Monad is a math notion.
Conal
+1  A: 

Yes, Monads comes from a concept outside of haskell. Haskell have many terms and Ideas that have been borrowed from Category theory. This is one of them. So if this person who is not a programmer turns out to be a mathematician who have studied Category theory, just say: "a Monad is a monoid in the category of endofunctors."

HaskellElephant
I don't know much about modads, but as a former mathematician that has some experience with Category theory, I think your answer is the best one here.
FarmBoy
+2  A: 

It depends on who you are talking to. Any explanation has to be pitched at the right level. My explanation to a chemical engineer would be different to my explanation to a mathematician or a finance manager.

The best approach is to relate it to something in the expertise of the person you are talking to. As a rule sequencing is a fairly universal problem, so try to find something the person knows about where you say "first do X, then do Y". Then explain how ordinary programming languages have a problem with that; if you say "do X, then do Y" to a computer it does X and Y immediately without waiting for further input, but it can't do Z in the meantime for someone else; the computer's idea of "and then do" is different from yours. So programmers have to write their programs differently from the way that you (the expert) would explain it. This creates a gap between what you say and what the program says. It costs time and money to cross that gap.

Monads let you put your version of "and then do" into the computer, so you can say "do X and then do Y", and the programmer can write "do {x ; y}", and it means what you mean.

Paul Johnson
+2  A: 

From this excellent post by Mike Vanier,

One of the key concepts in Haskell that sets it apart from other programming languages is the concept of a "monad". People seem to find this difficult to learn (I did as well), and as a result there are loads of monad tutorials on the web, some of which are very good (I particularly like All About Monads by Jeff Newbern). It's even been said that writing a monad tutorial is a rite of passage for new Haskell programmers. However, one big problem with many monad tutorials is that they try to explain what monads are in reference to existing concepts that the reader already understands (I've even seen this in presentations by Simon Peyton-Jones, the main author of the GHC compiler and general Haskell grand poobah). This is a mistake, and I'm going to tell you why.

It's natural, when trying to explain what something is, to explain it by reference to things the other person already knows about. This works well when the new thing is similar in some ways to things the other person is familiar with. It breaks down utterly when the new thing is completely out of the experience of the person learning it. For instance, if you were trying to explain what fire is to a caveman who had never seen a fire, what would you say? "It's kind of like a cross between air and water, but hot..." Not very effective. Similarly, explaining what an atom is in terms of quantum mechanics is problematic, because we know that the electron doesn't really orbit around the nucleus like a planet around a star, and the notion of a "delocalized electron cloud" doesn't really mean much. Feynman once said that nobody really understood quantum mechanics, and on an intuitive level that's true. But on a mathematical level, quantum mechanics is well-understood; we just don't have a good intuition for what the math really means.

How does this relate to monads? Time and again, in tutorials, blog posts and on the Haskell mailing lists, I've seen monads explained in one of two supposedly-intuitive ways: a monad is "kind of like an action" or "kind of like a container". How can something be both an action and a container? Aren't these separate concepts? Is a monad some kind of weird "active container"? No, but the point is that claiming that a monad is a kind of action or a kind of container is incorrect. So what is a monad, anyway?

Here's the answer: A monad is a purely abstract concept, with no fundamental relationship to anything you've probably ever heard of before. The notion of a monad comes from category theory, which is the most abstract branch of mathematics I know of. In fact, the whole point of category theory is to abstract out all of the structure of mathematics to expose the similarities and analogies between seemingly disparate areas (for instance, between algebra and topology), so as to condense mathematics into its fundamental concepts, and thus reduce redundancy. (I could go on about this for quite a while, but I'd rather get back to the point I'm trying to make.) Since I'm guessing that most programmers learning Haskell don't know much about category theory, monads are not going to mean anything to them. That doesn't mean that they need to learn all about category theory to use monads in Haskell (fortunately), but it does mean that they need to get comfortable thinking about things in a more abstract way than they are probably used to.

Please go to the link at the top of the post to read the full article.

missingfaktor
Wow... so its as practically useless to most people as I always thought it was. Just like calculus or any branch of physics that cannot be observed in a game of baseball (http://www.amazon.com/Physics-Baseball-3rd-Robert-Adair/dp/0060084367).
StingyJack
+5  A: 

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 world
y :: 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).

RD1
Wow, that's an *excellent* way of looking at it--it makes the causal structure more tangible, and I think could also be extended to show clearly why `Monad` can embed flow control but `Applicative` can't. In fact, I think that's the only good description of monads I've ever heard that doesn't start from functors or the operational behavior of a program. I'll definitely need to read that paper, thanks!
camccann
Thanks - this view is common in ML circles (particularly CMU), but less so for Haskell. Perhaps adding something like the above to the "Monads" Wikipedia page is appropriate? BTW that paper is firstly about formulating modal logic - having done that, "possibility" and "necessity" correspond to an abstract monad-comonad pair. To get strong monads (like Haskell) you restrict so that all assumptions are necessary. Or you can model effects that strong monads can't like thread migration to a remote host - see most of: http://www.cs.cmu.edu/~jwmoody/pub.html http://www.cs.cmu.edu/~tom7/papers/
RD1