
David Menendez wrote:
Be sure to read sigpfe's "You could have invented monads!" and the Wadler paper.
http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html
http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf
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 theory.
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 for me. 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 instances. 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 type-class! 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 side-effects. (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 instances. 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?" -- Ron