很难在安德烈(Andrej)或尼尔(Neel)的解释中添加任何内容,但我会试一试。我将尝试从句法观点出发,而不是试图揭示底层语义,因为解释是更基本的,并且我将为您的问题提供更直接的答案。
λ微积分中而不是在Haskell基础上的更复杂的系统中工作。我特别相信类型变量的存在可能会在一定程度上使您感到困惑。
关键参考如下:
Mendler,N。(1991)。二阶λ演算中的归纳类型和类型约束。恐怕我没有在网上找到参考。但是,这些声明和证明可以在Nax的博士学位论文中找到(强烈建议阅读!)。
B 一个d
B a d = B a d → A
一种
λ X :B 一个d。x x :B a d → A
所以
(λ X :乙一个d。X X )(λ X :乙一个d。X X ):甲
B a d =F(B a d)
F(X)XF(X)
当然,您不是在使用方程式定义的类型,而是在使用构造函数,即
data Bad = Pack (Bad -> A)
而不是严格的平等。但是你可以定义
unpack :: Bad -> (Bad -> A)
unpack (Pack f) = f
这足以使该结果继续成立:
(\x:Bad -> unpack x x) (Pack (\x:Bad -> unpack x x))
一种
在第二个示例中,事情有些棘手,因为您有一些类似的东西
B a d = B a d′→ A
B 一个d′B 一个d乙一个d一 B 一个d( Ñ ö 吨一)
type Not a = a -> False
与
data Not a = Not a
如果Haskell允许这样的类型定义,将很容易解决:
type Acc = Not Acc
在这种情况下,您可以按照与以前完全相同的方式构建循环组合器。我怀疑您可以使用以下方法进行类似(但更复杂)的构造
data Acc = D (Not Acc)
这里的问题是要建立同构
Bad Acc <-> Bad (Not Acc)
您必须处理混合方差。