我在读documentation on monad layers package,我的大脑会沸腾起来。不变函数的例子?
在本文的mmtl
部分中,作者谈论了不变函子。它的方法invmap
就像Functor
的fmap
,但它也需要逆态射(b -> a)
。我明白为什么作者说的MFunctor
比tmap
的Invariant
更强大,但我不明白逆向态射的重点。
是否有Invariant
的任何示例,它不能是Functor
的实例?
我在读documentation on monad layers package,我的大脑会沸腾起来。不变函数的例子?
在本文的mmtl
部分中,作者谈论了不变函子。它的方法invmap
就像Functor
的fmap
,但它也需要逆态射(b -> a)
。我明白为什么作者说的MFunctor
比tmap
的Invariant
更强大,但我不明白逆向态射的重点。
是否有Invariant
的任何示例,它不能是Functor
的实例?
这里是一个标准的地方,其中Invariant
显示 - 用于嵌入lambda演算的高阶抽象语法(HOAS)。在人道主义组织,我们喜欢写表达类型,如
data ExpF a
= App a a
| Lam (a -> a)
-- ((\x . x) (\x . x)) is sort of like
ex :: ExpF (ExpF a)
ex = App (Lam id) (Lam id)
-- we can use tricky types to make this repeat layering of `ExpF`s easier to work with
我们希望这种类型的有结构一样Functor
但遗憾的是它不能因为Lam
有a
S IN正反两方面的地位。所以不是我们定义
instance Invariant ExpF where
invmap ab ba (App x y) = App (ab x) (ab y)
invmap ab ba (Lam aa) = Lam (ab . aa . ba)
这真是悲惨的,因为我们真正想要做的是折叠此ExpF
自身键入以形成递归表达式树。如果这是一个明显的Functor
,但由于不是,我们会得到一些非常难看,具有挑战性的结构。
要解决这个问题,你添加其他类型的参数,并将其命名为参数的高阶像差
data ExpF b a
= App a a
| Lam (b -> a)
deriving Functor
而且我们最终会发现,我们可以在那里结合使用其Functor
实例变量替换建立一个免费的单子上面这种类型。非常好!
难道你不希望'Var b',因为'ExpF b a'只是一个'Fix',远离PHOAS – jozefg
我正在关注https://www.fpcomplete.com/user/edwardk/phoas。不过,在这一点上,'ExpF'基本上只是一个远离目标的'免费'。 –
'Data.Monoid'的Endo a'? – jozefg
是的,'Endo'应该是不变的。 – Carl
我认为这将是有益的,看看'逆变'。 –