[Haskell-cafe] Explaining monads
ronguida at mindspring.com
Sat Aug 11 15:00:04 EDT 2007
David Menendez wrote:
> Be sure to read sigpfe's "You could have invented monads!" and the
> Wadler paper.
> Most tutorials try to explain what a monad *is*, but these focus
> more on why they're a useful way to organize code. In my experience,
> being able to use a monad is more important than understanding the
Hey, now I know what a monad is! What I missed in all those tutorials
is that a monad is an *abstract base class*. With this realization,
which I had after reading the sigfpe tutorial, everything makes sense
To review a basic OOP example, I can't illustrate what a Vehicle *is*
in general terms. I can illustrate a Bicycle, a Car, a Boat, a Plane,
a Submarine, a Hovercraft, a LARC-V, and many other examples of
instances of /subclasses/ of Vehicle, but I can't find anything that's
/just/ a Vehicle. In OOP, Vehicle is an abstract base class.
The same thing applies for a Monad. I can look at lots and lots of
instances, like Maybe, Either, List, State, Reader, Writer, IO, and
lots of others, but I can't produce an example that's /just/ a Monad.
Monad is an abstract base class, too.
Now if I had to explain "What is a Vehicle", I would have to say "A
Vehicle is a device that provides transportation." When asked for
more details, I can specify the interface and provide examples of
Interface for Vehicle: load, unload, goto
Instances of Vehicle: Bicycle, Car, Plane, Boat, etc.
Given the question "What is a Monad", I would have to say "A Monad is
a device for sequencing side-effects." When asked for more details, I
can specify the interface and provide examples of instances.
Interface for Monad: return, bind
Instances of Monad: Maybe, Either, List, State, etc.
What is particularly stupefying for me is that I missed the fact that
Monad is "obviously" an abstract base class: Monad is declared as a
Now the hard part. As far I currently know - and I could be wrong:
(1) Monad, Comonad and Arrow are all abstract base classes.
(2) Monad, Comonad and Arrow are all devices for sequencing
(3) Monad and Comonad are both specializations of Arrow.
Given the question "What is an Arrow", I would have to say "An Arrow
is a device for sequencing side-effects." When asked for more
details, I can specify the interface and provide examples of
This leads directly to the question "What makes a Monad special,
compared to an Arrow?" Right now, the clues I have are:
(1) Every monad is equivalent to a Kleisli arrow.
(2) The ArrowApply class is equivalent to the Monad class.
I can restate the question: "What is special about ArrowApply,
compared to Arrow?" I see that an arrow accepts some inputs, performs
a computation, possibly with side-effects, and generates some outputs.
In particular, suppose I create instances of Arrow that accept two
inputs (as a pair) and produce one output. Some of these instances
(i.e. ArrowApply) are special: I can provide, as the two inputs, (1)
an Arrow that accepts one input and one output, and (2) an input
suitable for that Arrow. The output that I get is the result of
feeding input (2) to input (1) to get a result, *and* somehow
combining the side-effects of both arrows.
The only way an ArrowApply can combine the side effects of two arrows
and still obey the Arrow laws is through an operation that takes an
(arrow nested inside an arrow) and collapses it into a sigle arrow.
That's exactly what "join" does for monads. So, ArrowApply is
special, compared to Arrow, because ArrowApply has a join operation,
but Arrow doesn't. Clear as mud!
The question remains: "What is special about Monad or ArrowApply,
compared to Arrow?" or "What is more general about Arrow, compared to
Monad or ArrowApply?"
More information about the Haskell-Cafe