为什么Hindley-Milner算法永远不会产生类似t1-> t2的类型?


14

我在编写实现时正在阅读有关Hindley-Milner输入算法的信息,并且看到,只要绑定了每个变量,您总会得到原子类型或参数将确定最终类型的类型,例如t1 -> t1或。(t1 -> t2) -> (t1 -> t2)其中t1t2是类型变量。

我想不出一种方法,您将获得类似于t1 -> t2或简单的东西t1,据我所知,这意味着算法已被破坏,因为无法确定表达式的实际类型。您怎么知道只要绑定了每个变量,您就永远不会得到像“破”这样的类型?

我知道算法会产生带有变量的类型,但是一旦将参数传递给函数,这些变量就总是可以解决的,而带type的函数不会出现这种情况t1 -> t2。这就是为什么我想知道我们如何确定算法永远不会产生此类类型的原因。

(看来您可以在ML中获得这些“残缺的”类型,但我要询问的是lambda演算。)

Answers:


16

在Hindley-Milner类型系统的没有常量的Lambda演算中,如果函数的结果是未解析的类型变量,则无法获得任何此类类型。所有类型变量都必须在某处具有“来源”。例如,有类型的无术语,但有类型的术语∀ α α,β.αβα.αα(恒等函数)。λx.x

直观地说,类型的术语要求能够从稀薄的空气中构建出 β型表达。不难看出,没有具有这种类型。更准确地说,如果类型变量 β不在环境中的任何项变量的类型中出现,则不存在类型 β的项α,β.αββββ正常形式的。您可以通过对术语的结构归纳来证明这一点:要么头部的变量必须具有类型,要么其中一个自变量必须具有涉及β的主类型,即会有一个较小的合适术语。ββ

仅仅因为没有某种类型的值并不意味着就没有该类型的术语:可能存在一个没有值的术语,即一个非终止术语(准确地说,是没有范式的术语)。此类类型没有lambda项的原因是,所有类型良好的HM项都在高度归一化。这是对结果的概括,指出简单键入的lambda演算正在高度归一化。这是系统F高度标准化的事实的结果:系统F类似于HM,但允许在类型中的任何地方使用类型量词,而不仅仅是顶级。例如,在系统F中,具有式∀ α α ∀ αΔ=λx.xx -但 Δ(α.α)(α.α)的类型不正确。ΔΔ

HM和System F是具有Curry-Howard对应关系的类型系统的示例:类型明确的术语对应于某种逻辑的证明,类型对应于公式。如果一个类型的系统对应于一致的理论,则该理论不允许证明定理如 ; 因此没有相应类型的术语A,B,AB。类型系统允许人们推断关于数据结构上函数的“免费定理”。α,β.αβ

YY(λx.x)α.αA,B,AB

在确保强规范化的类型系统与没有强规范化的类型系统之间找到一条细线是一个困难而有趣的问题。这是一个重要的问题,因为它确定哪些逻辑是正确的,换句话说,哪些程序体现定理的证明。您可以比System F走得更远,但是规则变得更加复杂。例如,作为Coq证明助手的基础的归纳结构演算可以进行高度归一化,但能够描述它们之上的常见归纳数据结构和算法,等等。

一旦您使用了真正的编程语言,对应关系就会崩溃。真实的编程语言具有诸如通用递归函数的功能(可能不会终止),异常(总是引发异常的表达式永远不会返回值,因此在大多数类型系统中可以具有任何类型),递归类型(允许非终止)潜入)等


“这是系统F高度规范化的结果”。如何证明HM高度归一化是系统F高度归一化的结果?
拉斐尔·卡斯特罗

1
@RafaelCastro在HM中每个类型良好的术语在System F中都是类型良好的。在System F中每个类型良好的术语都是SN。因此,在HM中键入良好的每个术语都是SN。
吉尔(Gilles)'所以
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.