haskell - 如何推断递归函数的类型?

标签 haskell recursion type-inference hindley-milner

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

f = g
g = f

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

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

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

我如何推断这些类型?

最佳答案

在您的情况下,您需要推断 h 的类型并将其概括为多类型,然后再推断 fg 的类型.

如果我没记错的话,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 中,可怕的单态限制使这变得更加复杂,但如果我们没有类型类,我们可以忽略它。)

关于haskell - 如何推断递归函数的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67254536/

相关文章:

haskell - Haskell中反斜杠空格是什么意思

haskell - 如何使用 maybe 检测数独值

c++ - 模板大小递归——构造函数多重重载

c++ - 在 C++ 中实现原始递归组合器

haskell - 如何手动推断表达式的类型

java - 为什么这个带有绑定(bind)的泛型方法可以返回任何类型?

Java 类型推断 : reference is ambiguous in Java 8, 但不是 Java 7

haskell - 这两个函数类型定义有什么区别?

haskell - haskell中的 `sin sin 0.5`和 `sin (sin 0.5)`有什么区别?

javascript - 遍历我的主目录时出现 EPERM 错误的原因是什么?