Haskell 不变函子的例子?
我在看书,我的脑子快沸腾了 在本文档的Haskell 不变函子的例子?,haskell,functor,Haskell,Functor,我在看书,我的脑子快沸腾了 在本文档的mmtl部分中,作者讨论了不变函子。它的方法invmap类似于Functor的fmap,但它也需要逆态射(b->a)。我理解作者为什么说MFunctor的high比Invariant的tmap更强大,但我不明白这种逆态射有什么意义 有没有一个不变量的例子不能作为函子的实例?这里有一个标准的不变量出现的地方---嵌入lambda演算的高阶抽象语法(HOAS)。在HOA中,我们喜欢编写表达式类型,如 data ExpF a = App a a | La
mmtl
部分中,作者讨论了不变函子。它的方法invmap
类似于Functor
的fmap
,但它也需要逆态射(b->a)
。我理解作者为什么说MFunctor
的high
比Invariant
的tmap
更强大,但我不明白这种逆态射有什么意义
有没有一个
不变量
的例子不能作为函子
的实例?这里有一个标准的不变量
出现的地方---嵌入lambda演算的高阶抽象语法(HOAS)。在HOA中,我们喜欢编写表达式类型,如
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
我们希望这种类型的结构类似于函子
,但遗憾的是,它不能这样,因为Lam
在正反两个位置都有a
s。因此,我们定义
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
类型本身折叠起来,形成一个递归表达式树。如果它是一个函子
,那是显而易见的,但既然它不是,我们就会得到一些非常难看的、具有挑战性的构造
要解决此问题,请添加另一个类型参数并将其称为参数化HOA
data ExpF b a
= App a a
| Lam (b -> a)
deriving Functor
我们最终发现,我们可以使用它的
Functor
实例在这个类型上构建一个免费的monad,其中绑定是变量替换。非常好 Endo a
来自数据。幺半群
?是的,Endo
应该是不变的。我认为研究逆变
会很有用。既然ExpF b a
只是一个修复
远离PHOASI,你不也想要Var b
吗。在这一点上,ExpF
基本上只是一个Free
,离目标还有一段距离。