Hindley-Milner算法:使用类型来确保应用绑定

时间:2012-03-15 08:39:57

标签: haskell types unification

我正在实施Hindley-Milner类型推理算法,遵循Mark JonesOleg Kiselyov的教程。这两个都有一个“应用绑定”操作,其类型大致为

applyBindings :: TyEnv -> Type -> Type

tyvar -> ty TyEnv绑定应用于给定的Type。我发现在我的代码中忘记调用applyBindings是一个常见错误,而我从Haskell的类型系统中得不到任何帮助,因为tyapplyBindings tyenv ty具有相同的类型。我正在寻找一种在类型系统中强制执行以下不变量的方法:

  

在进行类型推断时,必须在返回'final'结果

之前应用绑定

在对单形对象语言进行类型推断时,有一种自然的方法可以强制执行此操作,如同使用thornton unification-fd package所实现的那样:我们为Type定义了两种数据类型:

-- | Types not containing unification variables
type Type = ...          -- (Fix TypeF) in wren's package

-- | Types possibly containing unification variables
type MutType = ...       -- (MutTerm IntVar TypeF) in wren's package

并提供applyBindings类型

-- | Apply all bindings, returning Nothing if there are still free variables
-- otherwise just
applyBindings :: TyEnv -> MutType -> Maybe Type

(此函数在unification-fd中实际为freeze . applyBindings)。这会强制执行我们的不变量 - 如果我们忘记applyBindings,那么我们会收到类型错误。

这是我正在寻找的解决方案,但是对于具有多态性的对象语言。目前的上述方法并不适用,因为我们的对象语言类型可能有类型变量 - 实际上,如果在应用绑定后存在变量,我们不想返回Nothing,但我们我们想要概括这些变量。

是否有我所描述的解决方案,即applyBindingsconst id不同类型的解决方案?真正的编译器是否使用Mark's和Oleg教程所做的相同的惩罚(在统一变量和对象语言类型变量之间)?

1 个答案:

答案 0 :(得分:5)

我在黑暗中捅了一下,因为我认为你提出的解决方案可能存在其他问题,但我至少可以解决一个难题:

  • 您的类型检查器应具有统一类型变量对象语言类型变量不同表示形式。

这种变化并不难实现,事实上我认为GHC类型检查器是这样工作的,至少在一次。您可能需要查看论文Practical Type Inference for Arbitrary-Rank Types;附录中包含许多非常有用的代码。