我无法理解为什么这些是他们各自教会数字最常见的类型:
2 = λf.λx. f (f x) : (α → α) → α → α
1 = λf.λx. f x : (α → β) → α → β
0 = λf.λx. x : β → α → α
我认为所有教会的数字都有相同的类型:
(α → α) → α → α
另外,我如何找到add运算符的常规类型
λm.λn.λf.λx. m f (n f x)
非常感谢任何帮助,谢谢!
答案 0 :(得分:2)
让我们从教会数字开始为零:
λf.λx. x : β → α → α
仅查看λf.λx.
部分,可以推断出我们有一个双参数函数,因此其类型为α → β → γ
,其中α
和β
代表参数'types和γ
代表结果类型。现在,正文x
进一步约束了类型:我们的函数的返回类型必须与其第二个参数的类型相同。这导致α → β → β
,或重命名后(α↔β):λf.λx. x : β → α → α
。这是零的最一般类型,因为我们没有使用f
应该是函数的事实,事实上,无类型 lambda演算中的教会零数字并不关心:它只是忘记了它的第一个论点。由于β
只是一个占位符,因此您可以将其专门化为α → α
,从而产生更具体的零类型 - λf.λx. x : (α → α) → α → α
。
让我们看一下1
:
λf.λx. f x : (α → β) → α → β
同样,它是一个双参数函数:α → β → γ
,但这一次(查看1
的主体)我们知道第一个参数f
是一个函数,所以{{ 1}}有一些f
类型,我们应该替换δ → ε
:α
。现在,我们知道我们必须能够将(δ → ε) → β → γ
应用于f
,这意味着x
的类型和x
的参数类型必须相等: f
= δ
,因此,我们已达到β
。但这并非我们所知,(β → ε) → β → γ
的类型为f x
,我们的数字会返回ε
,应用此信息后,我们会得到f x
= ε
。结合所有这些,我们到达γ
,或重命名后:(β → γ) → β → γ
。我们再次没有使用任何关于我们的使用意图的信息,这就是为什么我们有最常规的类型,当然,它可以是专门的(通过限制λf.λx. f x : (α → β) → α → β
= β
)到{ {1}}。
现在轮到α
了:
λf.λx. f x : (α → α) → α → α
这次我不会重复所有步骤,但是(作为中间步骤)我们可以到达2
。但请注意,这次我们将λf.λx. f (f x) : (α → α) → α → α
的结果输入自身:λf.λx. f (f x) : (α → β) → α → β
,这意味着f
的输入和输出类型必须相等,因此{{ 1}} = f (f x)
,这次最通用的类型是f
。
(*)请注意,Church β
,α
等具有与λf.λx. f (f x) : (α → α) → α → α
相同的最常规类型,因为多个功能应用程序不会给我们任何额外的信息,以进一步专门化类型。
关于加法函数3
,让我更简洁一点:
4
。2
是2个参数的函数:λm.λn.λf.λx. m f (n f x)
必须限制为α → β → γ → δ → ε
m
相同:α
必须限制为α' → α'' → α'''
n
和β
的第一个参数具有相同的类型,即β' → β'' → β'''
的类型:m
= n
= {{ 1}} f
的第二个参数类型为α'
β'
的结果类型等于γ
的第二个参数类型:n
= δ
n
m
β'''
让我们重命名变量,让它看起来更漂亮:
α''
的最常见类型是
n : γ → δ → α''
。
让我们检查它是否可以专门用于教会数字的二元运算
(m : γ → α'' → ε
= (γ → α'' → ε) → (γ → δ → α'') → γ → δ → ε
,λm.λn.λf.λx. m f (n f x)
= (β → γ → ε) → (β → α → γ) → β → α → ε
,β
= α → α
):
γ
。