“W 把类型方案、一阶统一和HM 推断组合成可实现算法。编译器可据此补全省略的类型、生成错误信息,并在中间表示中插入显式类型信息。”
形式陈述 ​
Hindley–Milner(HM)系统为带 λ、应用与 let 的纯函数核心语言提供隐式秩一参数多态。类型环境中的 let 绑定可具有类型方案,λ 绑定参数保持单态;规则通过实例化、泛化和一阶统一推导类型判断。
HM 具有主类型性质:若项
直觉
HM 的巧妙之处是让程序员省略类型参数和多数注解,编译器却仍能找到最一般的答案。应用产生“函数参数类型必须等于实参类型”的方程,统一算法传播这些等式;let 则把与外部环境无关的未知类型泛化,使同一函数在不同位置独立实例化。主类型像约束信息的最小承诺:它没有过早选定具体类型,却能生成所有合法特例。秩一限制牺牲了把任意多态函数作为参数的表达力,换来可判定、完备的推断。
例子与边界
对组合函数 λf. λg. λx. f (g x),推断得到
它是所有具体组合函数类型的主类型。let id = λx.x in (id 0, id true) 通过 let 泛化成立,而把 id 改成普通 λ 参数时不再自动获得多态实例。
边界来自效果与更高阶多态。若把一次可变引用分配的结果任意泛化,可能在同一位置写入不同类型的值,因此 ML 类语言采用值限制。多态递归和高秩类型一般不能由标准 HM 自动推断,需要注解或更强约束求解。
推论与应用
HM 奠定 ML、OCaml、Haskell 核心类型推断的基础。类型方案表达 let 多态,一阶统一求解约束,Algorithm W 给出构造性主类型算法。
主类型支持模块化错误定位和泛型库复用;现代语言常让 HM 推断服务于代数数据类型构造与模式,但和、积、递归的数据定义不是 HM 核心推断规则的前置。双向类型检查则以局部的 synthesis/checking 方向和必要注解组织信息,区别于 HM 通过全局约束统一寻找主类型。类型类、行多态与效应等扩展还需分别管理它们对可判定性和主类型的影响。
参考资料
- Benjamin C. Pierce, Types and Programming Languages, MIT Press, 2002,Ch. 22。
- Robin Milner, “A Theory of Type Polymorphism in Programming,” Journal of Computer and System Sciences 17(3), 1978,pp. 348–375。
- Luis Damas and Robin Milner, “Principal Type-Schemes for Functional Programs,” POPL, 1982,pp. 207–212。