Monad tutorial, Part 4
The State monad is a big jump for the monad-learner. It jumps up a level of abstraction by using functions as values. That makes it confusing because you have functions that work on functions, and it can be hard to keep track of whether a particular function is a this-kind-of-function or a that-kind-of-function. I try to tease apart the Gordian Knot thusly:
-
I start by creating a logging monad that simply logs the value of each step. This is fairly straightforward.
-
Next, I decide I want only particular steps to be logged. Steps to be logged use a
log
function which returns either a plain value or a wrapped value. That leads to anif
statement in the “decider”. -
Then I raise the question: can we get rid of the
if
statement by pushing its work down into thelog
function? In this section of the tutorial, I do something like follow Beck’s rules of design: make a series of undirected local changes that arrive at something globally coherent. Specifically, that first simple decision of pushing work into one place forces us to implement the full State monad (though I only show it used for building a log). -
Finally, I use that solution to illustrate some key concepts: base values, monadic functions, monadic values, and how they’re put together to make up a monad.
I have my doubts about how well this works, particularly the 3d step. I’d value your opinion.
March 22nd, 2011 at 12:39 pm
Congratulations for this great series. I think there is a little error in your definition of the logging-decider (minute 21) because you gave the same name to the parameter (which should be step-fn) and the :value part of the monadic-value (which should be step-value). Am I wrong and I complete misunderstood it?
Thanks.
Juan Manuel
March 30th, 2011 at 4:40 pm
Yes, you’re right. Since I managed to convince myself you were wrong for a moment (meaning the code is unnecessarily confusing), let me give more detail. Here’s the code: https://gist.github.com/895525 (can’t embed in a comment, and ordinary formatting is messed up).
As I explain later in the video, the value of the first argument to
logging-decider
(1) is a monadic (or wrapped) value. In this particular case, the wrapper is a function. At (2), that function should be called to extract a two-part thing: the value that someone reading only the domonad code would be thinking about and the log that is only seen behind the scenes in the monad-definition code. But instead of calling the first argument tologging-decider
, I called the value of a symbol (step-fn
) that has no value.I think I started with
step-value
, realized that a better name would bestep-fn
, and only made the change in one of two places.