recursion - 相互递归的类型推断

标签 recursion types ocaml type-inference

我一直在思考类型推断如何在以下 OCaml 程序中工作:

let rec f x = (g x) + 5
and g x = f (x + 5);;

当然,该程序毫无用处(永远循环),但是类型呢? OCaml 说:

val f : int -> int = <fun>
val g : int -> int = <fun>

这正是我的直觉,但是类型推断算法如何知道这一点?

假设算法首先考虑“f”:它可以得到的唯一约束是“g”的返回类型必须是“int”,因此它自己的返回类型也是“int”。但它无法通过“f”的定义推断其参数的类型。

另一方面,如果它首先考虑“g”,它可以看到它自己的参数的类型必须是“int”。但如果之前没有考虑过“f”,它就无法知道“g”的返回类型也是“int”。

它背后的魔力是什么?

最佳答案

Say the algorithm considers "f" first: the only constraint it can get there is that the return type of "g" must be "int", and therefore its own return type is also "int". But it cannot infer the type of its argument by the definition of "f".

它无法将其推断为具体类型,但它可以推断出某些内容。即:f 的参数类型必须与g 的参数类型相同。所以基本上在查看了 f 之后,ocaml 就知道了以下关于类型的信息:

for some (to be determined) 'a:
f: 'a -> int
g: 'a -> int

查看g后,它知道'a必须是int

要更深入地了解类型推断算法的工作原理,您可以阅读有关 Hindley-Milner type inference 的维基百科文章或this blog post ,这似乎比维基百科的文章友好得多。

关于recursion - 相互递归的类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3913763/

相关文章:

c# - 在 C# 中,Type.FullName 何时返回 null?

ocaml - `let` 来自 ocaml 中记录的字段双关

types - 在 OCaml 中键入没有 "polluting"模块的构造函数别名

c - OCaml 垃圾收集幻像类型

recursion - 在 F# 中定义递归函数内部函数与外部函数的性能副作用是什么?

Python:尝试将字符串转换为 int,对于以 10 为基数的 int(),出现 int 无效文字错误: ''

c++ 自动覆盖有符号/无符号

c++ - 递归时的段错误

Java递归斐波那契值

r - 使用 write.csv (base R) 保留数字作为字符字段