我正在按照Mark Jones和Oleg Kiselyov的教程实现 Hindley-Milner 类型推理算法。这两个都有一个“应用绑定”操作,其类型大致为
applyBindings :: TyEnv -> Type -> Type
它将tyvar -> ty
绑定应用于TyEnv
给定的Type
. 我发现在我的代码中忘记调用是一个常见错误applyBindings
,而且我没有从 Haskell 的类型系统中得到任何帮助,因为ty
它与applyBindings tyenv ty
. 我正在寻找一种在类型系统中强制执行以下不变量的方法:
在进行类型推断时,必须在返回“最终”结果之前应用绑定
在为单态对象语言进行类型推断时,有一种自然的方式来强制执行这一点,正如在 wren ng thornton 的unification-fd 包中实现的那样:我们为 s 定义了两种数据类型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
(这个函数实际上freeze . applyBindings
在unification-fd中)。这强制了我们的不变量——如果我们忘记了applyBindings
,那么我们将得到一个类型错误。
这是我正在寻找的解决方案,但对于具有多态性的对象语言。就目前而言,上述方法并不适用,因为我们的对象语言类型可能具有类型变量——事实上,如果在应用绑定后有自由变量,我们不想 return Nothing
,但我们想概括一下这些变量。
有没有按照我描述的思路的解决方案,即提供applyBindings
不同类型的解决方案const id
?真正的编译器是否使用与 Mark 和 Oleg 的教程相同的双关语(在统一变量和对象语言类型变量之间)?