←back to thread

A list is a monad

(alexyorke.github.io)
153 points polygot | 1 comments | | HN request time: 0.206s | source
Show context
kevinventullo ◴[] No.44450020[source]
So I come at this from a math background but I’ve always found these explanations to be overly complex. In the parlance of C++, I think of a monad as a template class T with the following properties:

1. For any class X, there is a canonical method

  F: X -> T<X>
2. For any class X, there is a canonical method

  G: T<T<X>> -> T<X>.
3. For classes X and Y, and any method

  f: X -> Y, 
there is a corresponding method

  “T<f>”: T<X> -> T<Y>.

—————-

Here “any type” means any type that is compatible with the template.

And then there’s some additional rules which make all these methods compatible, based on the different ways of stacking nested T’s and the “canonical” maps you get. Admittedly there is some confusing accounting here, but I also think most natural ways of constructing the above three requirements are going to satisfy them anyway. For List and Maybe it’s fairly obvious what the above methods are.

I dunno, maybe I have it wrong and someone can correct my understanding.

replies(4): >>44450173 #>>44450198 #>>44453789 #>>44457984 #
Kranar ◴[] No.44450198[source]
This is like explaining chess by simply stating the rules. Like sure explaining the rules of chess is important but only knowing the rules provides for nothing more than a superficial understanding of a topic.
replies(2): >>44450545 #>>44451158 #
kevinventullo ◴[] No.44450545[source]
I mean if someone is learning chess for the first time, then yes you should start with the rules rather than jumping right into waxing philosophic about positional strategy to show off how smart you are.
replies(2): >>44450885 #>>44451464 #
1. flebron ◴[] No.44450885[source]
I think the point is that a monad is a useful concept _purely_ because of what it _allows_ you to do, and _not_ because of anything syntactical. Those rules that you're obviating there, the commutative squares, are precisely what then lets us have powerful intuitions about these objects. The type signatures matter a lot less. If, for example, you don't have functoriality (which is false for `std::vector`, for instance, since `std::vector<bool>` is special-cased) you lose the ability to reason powerfully about abstract algorithms.

Thus, explaining the syntax and where the type variables go is explaining the least relevant thing about monads to their power and importance. It's certainly easy to showcase both the syntax and the list and maybe monads, that's part of the "monad tutorial fallacy". Gaining intuition for how to think about monads _in general_ is a lot harder and requires practice. Like, yes, list and maybe are "containers", but is `(->) t` a container? Is `IO`? How do these compose, if at all? What is this about "effect" semantics, "I thought monads were just burritos/containers"? etc. These are the hard, both conceptually and pedagogically, questions. Yes you need to know the syntax to use it in any given programming language, but knowing what scabbard your knife fits in doesn't give you the skills of how to use knife :)