4

我正在尝试使用基于 Hindley-Milner 算法的类型推断来实现语言。但我不知道如何推断递归函数的类型:

f = g
g = f

f在这里,我必须为和一起生成和解决约束,g因为如果我早些时候为一个函数执行此操作,它将不知道另一个函数的类型。但我不能同时对模块中的所有功能执行此操作:

f = h 0
g = h "str"
h _ = 0

fI haveh :: Int -> Int和 in gI haveh :: String -> Int中,如果我同时解决它会产生错误,但如果我将推断h之前类型的类型fgh :: forall a. a -> Int并且可以用于fg不同的替换a),则不会产生错误。

我如何推断这些类型?

4

1 回答 1

4

在您的情况下,您需要在推断 and 的类型之前推断出的类型并将h其概括为多型。fg

如果我没记错的话,Haskell 在这种情况下使用的策略是计算依赖图(哪个标识符取决于哪个标识符),然后将图分成强连接的组件。这提供了定义之间的一种排序,然后对其进行相应处理。

例如,在

f = using1 g h
g = using2 f
h = something

我们有 SCC {h}, {f g},我们将它们排序为

{h} < {f, g}

因为 SCC{f,g}取决于{h}. 然后我们推断 的多型h,并在推断f和期间使用它g

在一般情况下,我们得到 SCC 之间的偏序,这用于驱动拓扑排序算法,该算法在每一步推断类型。

(在 Haskell 中,Dreaded Monomorphism Restriction 使这变得更加复杂,但如果我们没有类型类,我们可以忽略它。)

于 2021-04-25T15:13:26.647 回答