Hindley Milner type inference for mutually recursive functions

suh*_*hwi 5 compiler-construction ocaml haskell functional-programming hindley-milner

I'm making a strongly typed toy functional programming language. It uses the Hindley Milner algorithm as type inference algorithm.

Implementing the algorithm, I have a question on how to infer types of the mutually recursive functions.

let rec f n = if n == 0 then 0 else g (n - 1)
let rec g n = if n == 0 then 0 else f (n - 1)
Run Code Online (Sandbox Code Playgroud)

f and g are mutually recursive functions. Now, when the type checker is inferring the type of function f, it should also be able to infer the type of function g, since it is a subexpression.

But, in that moment, function g is not defined yet. Therefore, the type checker doesn't even know the existence of function g, as well as the type of function g, obviously.

What are some solutions that real world compilers/intepreters use?

Pat*_*atJ 4

在 OCaml 中,相互递归的值由关键字而and不是另一个分隔let rec。当类型系统到达递归定义时,它将所有递归名称添加到环境中,然后像平常一样继续。

更新(感谢 KA Buhr):

完全有可能创建一个具有类型'a'a新鲜)的新变量,然后将其统一。确保在正确的位置概括变量(通常在定义之后)。

  • 啊,但是从推断单个递归函数的类型的更简单的问题开始(想想“阶乘”)。当它依赖于编译器在定义时未知类型的函数(即自身)时,如何“直接”推断其类型?同样,答案是在定义它时为其分配一个新的类型变量。因此,对于相互递归函数的块(包括单个递归函数的特殊情况),您实际上希望将新的类型变量分配给所有函数,然后开始推断它们的类型。 (7认同)
  • 通常,它会为它们分配一个新的类型变量,并让常规统一过程处理其余的事情。这与处理单个递归函数的方式相同。 (6认同)
  • 这个答案可能会有所帮助:/sf/answers/63330081/。请注意,即使评论说答案是错误的,它们也意味着这不是所提出问题的正确答案,但它确实解决了您的问题(并解释了 @PatJ 关于正确概括时间的注释)。然而,这对于评论来说太复杂了。您可能想将其作为一个单独的问题来问。 (2认同)