I'm reading documentation on monad layers package and my brain is going to boil up.
In the mmtl
section of this document the author talks about invariant functor. It's method invmap
is like fmap
of Functor
but it takes an inverse morphism (b -> a)
also. I understand why author says that hoist
of MFunctor
is more powerful than tmap
of Invariant
but i don't see what's the point of that inverse morphism.
Is there any example of an Invariant
which can't be an instance of Functor
?
Here's a standard place where
Invariant
shows up---higher order abstract syntax (HOAS) for embedding lambda calculus. In HOAS we like to write expression types likeWe'd love for this type to have structure like
Functor
but sadly it cannot be sinceLam
hasa
s in both positive and negative position. So instead we defineThis is really tragic because what we would really like to do is to fold this
ExpF
type in on itself to form a recursive expression tree. If it were aFunctor
that'd be obvious, but since it's not we get some very ugly, challenging constructions.To resolve this, you add another type parameter and call it Parametric HOAS
And we end up finding that we can build a free monad atop this type using its
Functor
instance where binding is variable substitution. Very nice!