我一直认为在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
关键字会出现语法错误?
答案 0 :(得分:19)
所有“成员”函数都在其定义的类型中隐式“rec”。
答案 1 :(得分:17)
'let rec'不是关于定义递归函数,而是定义环境中的绑定,包括当前绑定 要绑定的变量。您也可以使用'let rec'来定义,例如无限的清单。通常,您不希望包含绑定 在环境中,因为您可能希望以相同的名称访问早期变量。
当你定义静态成员函数factorial时,你不是在寻找变量'factorial'的绑定,而是为了一个类型 'MyRecordType'(在环境中作为类型定义),如果碰巧有一个名为'factorial'的静态成员函数, 它有。