Re:A Gentle Intro to Monads … Maybe?
by Mithaldu on Friday January 17, 2014 @02:40PM
(#7077959)
That sounds nice and all, but i still don't know why you contradicted yourself.
[ Parent
| on HN ]
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.