Pure functional languages have this advantage: all flow of data is made explicit. And this disadvantage: sometimes it is painfully explicit.

That’s the problem monads solve: they let you leave implicit some of the repetitive code otherwise required by functional programming. That simple but critical point left out of many monad tutorials.

Dan Piponi wrote a blog post You Could Have Invented Monads! (And Maybe You Already Have) very much in the spirit of Wadler’s paper. He starts with the example of adding logging to a set of functions. You could have every function return not just the return value that you’re interested in but also the updated state of the log. This quickly gets messy. For example, suppose your basic math functions write to an error log if you call them with illegal arguments. That means your square root function, for example, has to take as input not just a real number but also the state of the error log before it was called. Monads give you a way of effectively doing the same thing, but conceptually separating the code that takes square roots from the code that maintains the error log.

Post navigation

19 thoughts on “Monads are hard because …”

I still think many more people would understand monads better if one of the good tutorials used a language other than Haskell or Scala to teach the idea. There is room for a better understanding of the topic among people who don’t program in such languages, and understanding monads better might lower the psychological barrier to learning Haskell for some.

One of the best ways to see if you understand something is to try to explain it to someone else. Once I had my monad Aha! moment I too came up with an analogy and figured out how I would use it as part of a monad tutorial.

The problem with monad tutorials is that people don’t realize that the bulk of them are for the benefit of the writer, not any prospective reader.

Trouble with attempts to demo monads in other languages is that all other languages already impose their own idea of effects, so the demo is continually fighting that, which makes it really hard to see the point. Google for monad in Java for some examples.

as a very understandable, burrito-free explanation of Haskell’s type system, monads, functors, etc. It is what demystified monads for me. The next thing to read after that is the Typeclassopedia. Wadler’s paper is nice but not explicit enough IMHO.

@techtangents: I’ve been modelling my monads in C# with a class representing the higher order generic along with a combined class that has the three monad functions (pure/point/return, map, and bind/flatMap).

> That’s the problem monads solve: they let you leave implicit some of the repetitive code otherwise required by functional programming.

But that’s not a specialty of monads; generally higher-order functions are good at that. I think you may have come to the conclusion that monads do things implicitly because in Haskell there is special syntax for it (do-notation, where roughly speaking (>>=) is implicit).

More mathematically (as you understand much better than me) a monad is a functor f with “injection” (return :: a -> f a) and “merging” (join :: f (f a) -> f a or equivalently the (>>=) or (>=>) functions) with some nice commuting properties. Fundamentally there isn’t anything more to it.

Now why are monads abundant in programming? Computation often is “dirty”. It may have side effects (IO), it may possibly fail (Maybe, Either), it may be indeterministic (List), it may have state (State), it may be only symbolical (free monad), etc.

But while we can not get rid of it, we often would like to reason without the dirt. For example, while there is only the dirty (readFile :: FilePath -> IO String) we would like to think (readFile :: FilePath -> String) . Now if you have a function which acts depending on the contents of a string, (act :: String -> IO ()) you would not be able to apply it to the return value of (readFile).