“W 把类型方案、一阶统一和HM 推断组合成可实现算法。编译器可据此补全省略的类型、生成错误信息,并在中间表示中插入显式类型信息。”
“固定纯Hindley–Milner语言,项由变量、整数和布尔常量、λ、应用、非递归 let 与二元组构成。单态类型和方案为”
定义Definition
施工中 · 内容逐步修订
Type scheme · Polytype
通过显式量化类型变量表示一族单态类型的多态对象。
类型方案是表达参数多态的一种方式。先固定通常的 Hindley–Milner 情形,所有量化变量的种类都是值类型 Type,方案形如
的多态类型,其中
未被量化的类型变量仍受当前上下文约束,不能任意实例化。
记录行系统可在这个外层量化结构上加入种类和约束。这里另取两种种类:Type 表示单态值类型,Row 表示有限、标签不重复的字段行,允许一个尚未确定的行变量作尾部。记录构造 Row 变成 Type。相应方案写为
其中 Type 变量换成新鲜值类型变量,Row 变量换成新鲜行变量;同一个绑定变量的所有出现共享同一个新变量。替换同样作用于
例如
允许实例
对这份扩展,自由变量还要计入 Type 且
类型方案不是一个“包含未知量的单类型”,而是一份可反复生成单态实例的模板。每次使用多态变量都要把量化变量换成新的类型变量,否则两次调用会被错误地强迫成同一类型。泛化时排除环境中的自由变量同样关键:这些变量代表外部已经共享的约束,擅自量化会把一份单态资源伪装成多态。类型方案位于可推断性与表达力的折中点,只提供外层全称量化,却足以覆盖大量泛型代码。
恒等函数的方案是 let id = λx.x in (id 0, id true) 中,两次读取 id 分别实例化为
边界是λ绑定参数:标准Hindley–Milner不会把 λf.(f 0, f true) 中的f自动视为多态方案,因而该项不可定型。高秩检查可在参数上显式保留∀,但须用刚性变量验证承诺;多态递归则要求递归体能看到完整方案,而非共享单态占位符。二者改变的是方案可以出现和实例化的位置,不是省略一次普通合一步骤。
类型方案是Hindley–Milner 类型推断中 let 多态的表示,Algorithm W在变量处实例化、在 let 处泛化。一阶统一只求解生成的单态约束,量化边界由方案机制管理。
在实现上,方案使泛型函数无需复制源代码即可安全复用;带可变状态的语言还需值限制,避免把具有分配效果的表达式不安全地泛化。
W的嵌套let账本让共享与泛化分别出现:由外层函数得到的结果类型仍自由出现在环境中,所以局部值不能泛化;忽略参数的函数只泛化新参数类型。该页同时给出方案替换避免捕获的具体例子。
Benjamin C. Pierce, Types and Programming Languages (2002), let-polymorphism and type schemes.
Robin Milner, A Theory of Type Polymorphism in Programming (1978), type polymorphism.
Benedict R. Gaster and Mark P. Jones, A Polymorphic Type System for Extensible Records and Variants, 1996,§§2–3:记录行、lacks 条件与受约束方案。
正在载入交互图谱…