I have been thinking about Reader monads, and the bothering-with thereof. Here's this morning's stream of consciousness...
Thought of the day - what’s the difference between using a function
foo :: Config -> SomeResult
and using the monad foo :: Reader Config SomeResult
?
Answer: Technically none. data Reader r a = Reader { runReader :: r -> a }
is really an equation saying they’re exactly equivalent: Reader r a
equals r -> a
.
So what’s the point of the Reader monad? Why (or rather, when) should you bother with a Reader monad instead of a straight argument?
Answer: composition. The Reader
version composes
(maps/sequences/etc.) trivially, to produce a single function that’s
just waiting for its config. The vanilla version requires more
plumbing (& thought) to compose.
Partly that’s offset in Clojure - we don’t just use functional composition, we can use syntactic composition too (because macros).
But that’s my conclusion of a night in the hammock. The Reader monad
is a transformational trick to enable easier functional
composition. And so, the “should I use it?” question follows as, “am I
doing a lot of config
plumbing to sequence these function calls?"