Justin du Coeur (jducoeur) wrote,
Justin du Coeur

Monads, monads everywhere

[Also aimed at programmers, although not necessarily the hardcore ones. And I have not woken up yet, so this one's a bit punchy.]

You know that you have internalized the concept of a Monad (and are a complete geek) when you are lying in bed, listening to WBUR in pledge-drive mode, and think, "So Fundraising is a Monad being applied to News. (I am such a geek.)" But y'know, it kind of works.

Monads are the big scary boogeyman of programming these days. I believe this is mostly because (a) the name is cryptic jargon, and (b) they all-too-often gets described in terms of the formal Category Theory that underlies them, rather than what you can *do* with them. But really, the basic notion is fairly straightforward. A Monad is basically a Wrapper that can be applied to an arbitrary Type, that works in a couple of useful ways.

The Monadologie video I linked to yesterday goes into this a bit better, but let's run with my ridiculous pledge-drive example. Say that we have a type TransmittedInformation, which has subtype PublicSupportedBroadcasting, which has subtype NPR, which has subtype NPRDay, which has subtype NPRProgram, which has subtype NPRStory. To any of these, we can apply the Fundraising[T] Monad, which takes the underlying type T and uses it as an opportunity to convince people to give us money.

Now a Monad needs to define two crucial functions -- in Scala terminology, these are unit and flatMap. (It also needs map, but that turns out to be derivable from the other two.) [WARNING: oversimplifications and inaccuracies in the name of humor ahead. But it should get the basic idea across.]

Monad.unit(T) is the function that takes a T and turns it into that Monad. So in the case of our example, Fundraising[T].unit() takes an object of type T and surrounds it at the beginning and end with talking heads who explain to you how important you are to them, and why you want to buy a membership so that you can win a chance to fly to the Galapagos Islands and look at Blue-Footed Boobies. (That was today's verbal tic. Once they established that the Galapagos has Blue-Footed Boobies, they took every opportunity to say "Blue-Footed Boobies", like Hobbes bouncing around yelling "Smock!")

Monad.flatMap(M[T1], f: T1 => M[T2]) is a sort of meta-function -- it takes a Monad of T1s, and a function that turns a T1 into a Monad of T2s, and combines all that to produce a flat Monad of T2s. That's clearer with an example. Say that each bit of our day has a constituentParts member -- NPRDay has NPRPrograms, which has NPRStories. So we can write this function:
  def fundraiseWithBoobies(programming: T1 <: NPR):Fundraising[T2 <:= T1] = {
    blatherAboutBoobies + programming + blatherAboutBoobies
That is, surround this bit of programming with discussion of sending them money to have a chance to go see Blue-Footed Boobies. Now, all Fundraising.flatMap() has to do is apply this to each of the contituent objects of some programming, and then combine them back together. So by applying flatMap(pledgeDrive, fundraiseWithBoobies), I get discussion of Blue-Footed Boobies every two minutes!

Seriously, though: calling a Wrapper a "Monad" mostly just means you know how to flatten a bunch of them into a single one. So List[T] is a Monad, because flatMap just concatenates multiple Lists. Option[T] (which is Scala's way of saying "this might or might not have a real value") is a Monad, because flatMap knows to produce None if any of them result in None. Set[T] is a Monad because it knows to combine the Sets, eliminating duplicates. Etc.

Why do we care? Mostly because it lets you build data pipelines without having to do all the grungy combination work yourself, resulting in DWIMmier code, so long as the language supports this pattern directly. The Monadologie video gives a couple of examples toward the end, and is well worth watching for those: one example is worth a thousand equations, and all that...
Tags: programming

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded