To borrow a turn of phrase from Norman Mailer, a programming language that prides itself on handling IO via category theory, has a problem. But I share that problem, to an extent.

I understand the seductive power of abstraction, but I think the Haskellians made a huge PR mistake in going all in on category theory. CT is by construction both bland and general: any formal system can be parsed into CT, but CT usually brings nothing new to the discussion. CT is abstraction for abstraction’s sake, i.e. pure mathematics, and there is no need for computer scientists to make a fetish of it.

Here’s my 10,000 ft view of monads. A monad is a derived type. For example, for any type t, F t might be a framed portrait of elements of type t. B t might be an element of type t produced by code partially written by a Beatles fan. More realistically C t might be container type for objects of type t, or a warning type that an object of type t has been contaminated by an impure procedure (e.g., IO).

Haskell provides some utilities to facilitate working with derived types. All the programmer has to do when defining a monad M is provide (1) a method for turning an object of type t into an object of type M t; (2) a method for turning a function defined on type t into a function defined on type M t.

This sort of thing is easy enough in Lisp, Mathematica, etc, and doable in any modern language. It’s perhaps easiest in Haskell but the fear and trembling surrounding monads are silly, and mostly result from poor explanations.

I lost most of my enthusiasm for Haskell when I discovered it has no good mechanism for memoizing recursive functions. By “good” I mean: it ought to be possible to define an operator *memo* so that “*memo fun*” yields a memoized version of the function *fun*. This can be done in Lisp and Python, to mention two extreme examples, but not in Haskell. The culprit seems to be immutability: the *memo* operator would have to be able to redirect recursive calls to *fun* to the new version, but that kind of redefinition is forbidden in Haskell. Please let me know if I’m wrong.