The biggest hurdle to my understanding monads was the insistence on using metaphors. Most mainstream languages don’t let you approach new concepts from a mathematical standpoint, and learning how to do that was necessary before I really grokked what a monad was. Fish, boxes, burritos–they all just confused me. A monad is a type that provides two functions:
These two functions obey three laws:
Left identity. Where f is a function that returns a wrapped value, and a is an unwrapped value:
bind (return a) f := f a
Right identity. Where m is an already-wrapped value:
bind m return := m
Associativity. Where f and g are functions that return wrapped values, and m is an already-wrapped value:
bind (bind m f) g := bind m (λx -> bind (bind x f) g)
Trying to put more metaphors on top of these laws was not helpful to me, because a lot of the metaphors fall down for different types of Monad. IO and State don’t feel like “boxes” in the same way that Maybe and Either types do, for example, and Identity doesn’t really have any inherent meaning.
So, you’re saying you would have liked the Zero-Analogy Monad Tutorial?
Because while it’s one of my favorite tutorials, I feel like this definitional focus fails to instill an operational understanding; i.e. it fails to help the learner answer the questions, “How do I use monads?”, “When do I use monads?”, and “How do I write a new monad?”
I do like that! I’d never seen it before. I think that the latter class of understanding is different: once you understand what it is, then you can give examples of how useful things relate to it in terms of the definition. You can scope your metaphors down to a more manageable level (like “railways” for Either), and actually get mileage out of them instead of confusing the issue with an illustration that doesn’t apply to the general case.
This explanation in Scheme was super helpful for me, as a non-Haskelliere. Or at least I think I understand monads now…