[Haskell-cafe] there's a monster in my Haskell!

To boost the popularity of Scheme, Felleisen has argued for renaming "lambda" to "something cool, such as Funster".[1] Likewise, Haskell intimidates newcomers with the arcane term "monad". Peyton Jones's hopeful campaign to replace it with "warm fuzzy thing"[2] has so far produced few results. Inspired by Felleisen, and in the spirit of Halloween, I offer a new alternative: Meet "monsters", your computational companions in the land of lazy functional programming. To illustrate this proposal, I present here a gentle introduction to monsters. Monsters come in great variety, each type having its own special powers. But, as noted by Elmo[3], they are alike in an essential way. All monsters are capable of devouring values: devour :: Monster m => a -> m a The result of "devour x" is simply a monster that has ingested the value "x". Most monsters have a weakness and can be slain, liberating some ingested values or producing some other result. The instrument of demise varies, as do the possible outcomes, so this function is particular to a monster. If SomeMonster always yields a single value upon its demise, we would have slay :: SomeMonster a -> a The compassionate (and fastidious) programmer defers the gruesome (and messy) slaying while making use of the monster's special powers. But how to get at the monster's values short of that macabre act? Fortunately, monsters gladly contribute their values towards the creation of more monsters: (>>=) :: Monster m => m a -> (a -> m b) -> m b (>>=) should be read as the monster on the left expelling values through its rows of teeth and over its tongue at the function on the right. (Its pronunciation is a sort of bestial hissing that is difficult to describe; when you say it correctly, the terminal may become slightly moist.) Monsters range from the tame to the tumultuous, but we cannot let them run entirely amok. All therefore must obey the "monster laws". For instance, the regurgitation law states that immediately after devouring a value, a monster expels the same value: devour x >>= k === k x We have still seen none of the promised special powers. For that, we must look at a particular monster. The Either monster is defined as data Either a b = Trick a | Treat b This monster devours Treats, but if it doesn't get a Treat, it can play a Trick: playTrick :: t -> Trick t a playTrick t = Trick t This monster is commonly used as follows: takeFood :: Food -> Either Mischief Food takeFood Apple = playTrick eggHouse takeFood Raisins = playTrick tpTree takeFood CandyCorn = devour CandyCorn The divine among monsters is the mysterious and awesome IO. Its powers are vast, perhaps limitless, and beginners are taught that it cannot be slain. Like poisoned candy and release dates, this is of course a myth. The pure of spirit may, after meditation at the altar of referential transparency, cast the spell :: IO a -> a (When you are prepared to call this function, its name will be revealed.) The ST monster can be slain without esoteric ritual: slay :: (forall s. ST s a) -> a Yet philosophers whisper that there is something otherworldly about it, a kinship with IO. Eavesdropping on their debates, I hear the words "phantom type", but that gives me the chills so I leave them. [1] http://permalink.gmane.org/gmane.comp.lang.lightweight/3427 [2] http://research.microsoft.com/~simonpj/papers/haskell-retrospective/ [3] http://muppet.wikia.com/wiki/We%27re_All_Monsters