2014-02-28 37 views
5

我在读documentation on monad layers package,我的大脑会沸腾起来。不变函数的例子?

在本文的mmtl部分中,作者谈论了不变函子。它的方法invmap就像Functorfmap,但它也需要逆态射(b -> a)。我明白为什么作者说的MFunctortmapInvariant更强大,但我不明白逆向态射的重点。

是否有Invariant的任何示例,它不能是Functor的实例?

+3

'Data.Monoid'的Endo a'? – jozefg

+0

是的,'Endo'应该是不变的。 – Carl

+2

我认为这将是有益的,看看'逆变'。 –

回答

4

这里是一个标准的地方,其中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但遗憾的是它不能因为Lama 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实例变量替换建立一个免费的单子上面这种类型。非常好!

+1

难道你不希望'Var b',因为'ExpF b a'只是一个'Fix',远离PHOAS – jozefg

+1

我正在关注https://www.fpcomplete.com/user/edwardk/phoas。不过,在这一点上,'ExpF'基本上只是一个远离目标的'免费'。 –