

What is a Monad? An Explanation That Makes Sense - darkxanthos
http://lambda-the-ultimate.org/node/1276#comment-14124

======
jasonkester
As somebody who didn't previously know what a Monad is (and still didn't after
reading that section), I'd disagree that the linked explanation makes sense.
I'd go as far as to say that it's not even an explanation, but rather a
clarification of the term intended for those who are already familiar with it.

Further, as somebody who didn't previously know what a Monad is (and now does
after reading the Burrito explanation linked in this thread), I'd suggest the
Burrito explanation as an example of one that does in fact make sense (and is
actually an explanation.)

~~~
barrkel
Here's my explanation of Monads, assuming one knows the basics of modern
imperative programming, and knows what a first-class function is (even
thinking of it as a function pointer will do, if you don't).

Monads are essentially a design pattern, an abstraction, for dealing with
items of some arbitrary type (call it "a") in some way.

Instead of working with values of type "a" directly, you work at one step
removed. You hand the value of type "a" off to the monad, and it hands you
back an opaque box (of type "M a") which logically contains your value. Now,
instead of operating on the value directly, you instead hand the box a
function that's supposed to apply to the contents of the box, and in return
you're given back a new box with the function applied to the contents of the
old box. That's basically it.

The interesting bit is that the monad - the box - sits between the function
you're trying to apply, and the value it's supposed to apply to. That gives it
the opportunity to do clever things. For example, the Maybe monad can keep
track of whether the box is empty or not, and only apply the function you pass
in if there's actually a value there. The List monad lets you apply operations
to multiple values as if it were only one value (i.e. it's like an implied
map). The IO monad takes in your function that's supposed to be applied to
(e.g.) whatever was read from input, and hands you back a box that appears to
contain the results of that operation. The catch is that the box is opaque -
you can never look inside it - so there's no way for you to tell, from the
outside, whether or not there were any side-effects. The IO monad can be
looked at in another way: you can think of it as queuing up all the actions to
perform on I/O, but actually building up an imperative program inside the box,
which only ever gets opened up and evaluated after your program has finished
its whole pure computation. (This is just a mental model for IO in the context
of pure functional programming, with no side-effects.)

Putting a value into the box is the unit operator, also called return in
Haskell. Passing in a function to the box and getting a new box in return is
the bind operator, spelled >>= in Haskell, but simplified by do notation.

~~~
andrewcooke
that's very neat, and basically what i understood by "monad" (although i
wouldn't have been able to express it so well).

however, as the burrito explanation makes clear (and the apple thread confuses
spectacularly) there's also some extra bits related to whether related boxes
are identical or not. and it's kind-of obvious that these are important,
because if you can't look into the box directly then you need to have some
idea of what makes some boxes different while others remain equal.

~~~
barrkel
For sure, and there are other details - for one, the function you pass in maps
the value from a -> M b, rather than a -> b. But I think the aha! moment is
the one you need to get to as quickly as possible where monads are concerned,
and then worry about the details later. I, for one, was mightily confused by
the Haskell do notation - I couldn't figure out why certain sequences worked,
and other orders of operations didn't, and I had no intuition of what way
types were flowing - it was the essence of a cargo-cult example.

And without some sufficiently abstract description of the thing, it's easy to
fail to generalize from the seemingly unrelated concepts as a Maybe type and
I/O.

------
jganetsk
I like the Monads are like Burritos one.
<http://blog.plover.com/prog/burritos.html>

~~~
paulgb
For me, monad tutorials that relied on analogies just complicated the concept
of monads.

If anyone else is in the same boat, I'd recommend this tutorial:
<http://www.haskell.org/all_about_monads/html/index.html>

Particularly Part II, which shows how some of the types that _you're already
familiar with_ are defined as monads. (I'd recommend skimming Part II before
reading Part I.)

------
olavk
Most programmers would probably prefer an explanation which focus on how
monads work and what they are useful for, rather than just an allegory
illustrating the type signature.

For a typical developer with some experience in OO programming, a more useful
analogy is with the _command pattern_.

In the command pattern, a "command" is an object which wraps a method call or
some other statement or operation. The "invoker" is a client which can execute
the command object. Command objects can be composed, so a compound command may
consist of a sequence (or tree) of other command objects.

Hence a compound command is basically a small program, just with a lot of
overhead since each statement is wrapped in a separate object. The benefit of
the pattern is that the invoker can add some additional logic to the
execution. For example the invoker could log state between each command
execution, it could allow a client to single step through the command-chain,
backtrack, replay and so on.

The command pattern could be used to e.g. implement exceptions in a language
which didn't support exceptions natively. You just wrap all statements in
command objects, and then have the invoker check the return value after each
command execution - if the return value indicates an error, the invoker does
not continue with the next command, but backtracks to the last "try" command.

In the same way it would also be possible to simulate continuations, parallel
executions or other advanced language features using the appropriate invoker-
logic. The pattern could be used to create all kinds of sublanguages with
different semantics than the host language.

Monads is the equivalent of this in a functional language. Rather than
wrapping operations in objects they are wrapped in closures.

The talk about apples trapped in boxes, burritos and so on, is just an attempt
to explain the rather obvious fact that command objects are not
interchangeable with ordinary values and statements. For example a command
might calculate and return a number. But you can't add that command object to
a ordinary number. You have to execute the command first and get the resulting
number before it can be added to an ordinary number. Conversely you cannot
insert an ordinary number or expression onto a chain of command objects. You
have to wrap it in a command object first, before it can be composed with
other commands.

------
tome
Not really. All that he's done is given an intuitive reason that the functor
Powerset from Set to Set is monadic. This is not a demonstration of monads in
general!

------
superkarn
I'm tempted to upvote this post just so the other people can see the comments.
Specifically the burritos link and the explanation by barrkel.

