Posted by harold at December 2nd, 2007

It seems like everybody and his brother (unless his brother makes web 2.0 sites with rounded corners) is clamoring to use Haskell these days. Mostly because they think it’s 31337, but have no idea how it actually works. This eventually devolves into a discussion of trying to figure out what the heck monads are. Well, I have another explanation, folks. And it involves an analogy.

Think about Schroedinger’s cat in the box. You can’t directly interact with the cat, but if you wanted to feed it, you could put a mouse in the box. And if you wanted to pet it, you couldn’t stick your hand in (’cause you’d be getting information out), but you could make a petting device and stick that in the box.

Well, folks, a monad M is basically a box. Something of type M a is a box with something of type a inside. For example, you could have an M cat where the type cat can have values LiveCat or DeadCat—but from outside the box, you don’t know which it is.

If you want to transform the a to a b, you have to make sure that all the information about the original a thing remain in the box. The only way to do this is to put a function of type a -> b into the box, with the instructions to apply it to the thing inside the box. For example, you might have an M cat and want to apply a function adorn that puts a little hat on the cat, which would have type cat -> (hat, cat). But hold on there! Now you need some help to put that function into the box.

The monad operations, explained elsewhere, are simply syntax for this intuition. The “return” function puts something into a box. The “bind” operation (>>= in Haskell) takes something in a box, and a function, and puts the function into the box and applies it to the thing inside. In Haskell, the function is actually expected to return something already in a box, so we’d have to compose return with our cat-hatting function (return . adorn), making something of type cat -> M (hat, cat). The rest is details.