【问题标题】:How can I infer types for recursive functions?如何推断递归函数的类型?
【发布时间】:2021-07-19 02:42:21
【问题描述】:

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

f = g
g = f

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

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

f 我有h :: Int -> Intg 我有h :: String -> Int,如果我同时解决它会产生错误,但如果我会推断h 的类型则不会fg 的类型之前(h :: forall a. a -> Int 并且可以在 fg 中使用不同的替换 a)。

如何推断这些类型?

【问题讨论】:

    标签: haskell recursion type-inference hindley-milner


    【解决方案1】:

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

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

    例如,在

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

    我们有 SCC {h}, {f g},我们将它们订购为

    {h} < {f, g}
    

    因为 SCC {f,g} 依赖于 {h}。然后我们推断出h 的多型,并在推断fg 的过程中使用它。

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

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

    【讨论】:

      猜你喜欢
      • 2018-07-29
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2020-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多