Monads in 300 words
Many contemporary languages have one or more of these features:
- Null propagation;
- Async/await;
- List comprehensions.
In the 90s, programmers observed that all of these can be modeled by a single interface.
They called the interface “monad” after a mathematical concept that looked similar.
With this interface, they could define a single syntax and utility library that covers all three.
Cute!
Why don’t other languages have monads?
Good question.
-
The language cannot express the concept.
The monad interface is generic over generic types – the List
in List<T>
.
Most languages can’t be generic like this, and the languages that can run into further problems down the line.
-
The language can already do it some other way.
For example, Scheme has first-class continuations that let the user override control flow in a similar way.
Building monads on top of that would be redundant.
-
The simplification isn’t that large in practice.
Most code only deals with a handful of monads.
So we can just define N syntaxes and call it a day.
Sure, there might be some duplication here and there – consider Option::flatten
vs Result::flatten
vs Iterator::flatten
– but who cares?
Haskell, a pure functional language with fancy types and a heavy runtime system, is in a perfect position to support monads.
But other languages have different goals in mind, and those goals might not align in the same way.
Should I care about monads?
If you are learning Haskell, or a similar statically-typed functional language, then understanding monads is a necessity.
(If you’re not, then I recommend it.
Functional programming is cool!)
But I don’t think reading tutorials is a good idea.
“Monad” is but a small part of Haskell as a whole.
Studying it in isolation, and expecting to understand anything, makes as much sense as learning Python through its descriptor system.
Instead, write code.
Play with async I/O.
Implement some type classes.
And at some point it’ll all make sense.