News for hackers. Stuff that matters.
Re:A Gentle Intro to Monads … Maybe? by tel on Friday January 17, 2014 @03:42PM (#7078273)
Okay, I'll explain it. Apologies for the apparent contradiction—I'm not trying to move the goal posts, just trying to avoid going into the weeds.

As I said, Python decorators are essentially just a syntax for function composition.

    @deco
    def g(args):           g := deco(g(args): body)
      body
where (g := a) means a is assigned to the name g. As it turns out, functions form a type which is a functor over the result type. The fmap (arrow map) is just function composition. In Haskell you would write this as

    instance Functor ((->) r) where
      fmap g f = g . f
where the (.) syntax is also function composition, very similar to the @deco syntax in Python. In this sense, I stated that @deco is a Functor.

Now, the function data type also admits a Monad instance (which some people abuse terminology to say "functions are monads" but I highly dislike that terminology when speaking carefully).

    instance Monad ((->) r) where
      return a = \_ -> a
      (f >>= g) x = g (f x) x
So in this way, the function type instantiates both Functor and Monad, but composition (which is (.) in Haskell and @deco is Python) is not directly related to the Monad.

Instead, a function's Monad instance allows us to "defer application" and translate something like

    \x -> (1 + x, 2 + x)
into

    do a <- (1+)
       b <- (2+)
       return (a, b)
In this format it's pretty stupid looking, but we also tend to call this monad instance the "Reader Monad" which indicates computations which occur under a fixed set of configuration information—some static global variables.

For instance, if I had a Key type which represented some encryption key I could change my encrypt and decrypt functions from

    encrypt :: Key -> String -> String
    decrypt :: Key -> String -> String
to

    encrypt :: String -> Reader Key String
    decrypt :: String -> Reader Key String
which, allows us to defer that extra `Key` argument until later.

So, that's what I meant by saying that @deco isn't the Monad that its Functor represents—it only has the composition aspect, not the deferred application aspect.

There are no comments on this comment yet.