【问题标题】:Function type inference with recursive calls递归调用的函数类型推断
【发布时间】:2013-03-03 21:49:57
【问题描述】:

我正在尝试实现一种自定义语言,该语言允许从最后一条语句中推断出函数返回类型。但是,当找到直接或间接的递归函数调用时,类型推断系统显然会失败。

func factorial(a:int) -> 
    if a == 0
        1
    else
        a * factorial(a - 1)

例如,即使参数类型未指定,F# 也会这样做:

let rec fact i =
    if i = 0 then 1 else i * fact (i-1)

这个系统是如何工作的?

【问题讨论】:

    标签: f# type-inference


    【解决方案1】:

    F# 类型检查器使用Damas-Hindley-Milner 类型推断算法。阶乘的例子大致可以解释如下:

    • 根据fact 的声明,我们的类型为tx -> tytx = t(i),其中t(i) 是值i 的类型。

    • 从相等性检查中,由于val (=): 'T -> 'T -> bool,我们也有t(i) = t(0) = int

    • then 分支,我们得到另一个约束ty = t(1) = int
    • else 分支,正常的(*) 运算符是'T -> 'T -> 'T,所以我们得到t(i) = ty

    基于约束集:

    tx = t(i)
    t(i) = t(0) = int
    ty = t(1) = int
    t(i) = ty
    

    使用统一,我们到达tx = ty = int 并推断fact 的类型为int -> int。这也意味着如果您更改if/then/else 中的子句顺序(通过反转条件),类型推断仍然可以正常工作。

    也就是说,这是类型推断算法的一个非常简单的示例。 您可以点击上面的 Wikipedia 链接了解更多信息。

    为了将算法应用于您的自定义语言,您可以在各种函数式编程书籍中找到实现。详情请看此帖Damas-Hindley-Milner type inference algorithm implementation

    【讨论】:

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