记录类型的递归成员函数和“rec”关键字

时间:2010-01-03 19:38:35

标签: f# recursion record

我一直认为在F#中我们需要为每个递归函数使用rec关键字,例如:

let rec factorial = function
| 0 -> 1
| k when k > 0 ->  k * (factorial (k - 1))
| failwith "oops!"

今天我正在玩F#,我想出了类似以下的代码:

let MyRecordType =
    { Something     : float;
      SomethingElse : int }
    with
        static member factorial = function
            | 0 -> 1
            | k when k > 0 ->  k * (MyRecordType.factorial (k - 1))
            | failwith "oops!"

如你所见,我刚刚定义了一个递归函数,但我最初看起来像是一个错误:我忘了通过{{1}将函数声明为递归 } keyword。

但令我惊讶的是编译!还有更多内容:如果您添加rec关键字,则表示语法错误!

rec

我已经搜索了一些解释,却一无所获。在MSDN文档中,我找不到the page about recursive functions之外type MyRecordType = { (* ... *) } with // syntax error: static member rec factorial = function (* ... *) 关键字的任何提及,截至2010-01-03,它没有提到我要问的情况。

非静态成员完全一样。

那么,为什么在记录类型的成员函数上使用rec关键字会出现语法错误?

2 个答案:

答案 0 :(得分:19)

所有“成员”函数都在其定义的类型中隐式“rec”。

答案 1 :(得分:17)

'let rec'不是关于定义递归函数,而是定义环境中的绑定,包括当前绑定 要绑定的变量。您也可以使用'let rec'来定义,例如无限的清单。通常,您不希望包含绑定 在环境中,因为您可能希望以相同的名称访问早期变量。

当你定义静态成员函数factorial时,你不是在寻找变量'factorial'的绑定,而是为了一个类型 'MyRecordType'(在环境中作为类型定义),如果碰巧有一个名为'factorial'的静态成员函数, 它有。