F# 记录类型递归成员函数和;rec";关键词
我一直认为,在F#中,我们需要对每个递归函数使用F# 记录类型递归成员函数和;rec";关键词,f#,recursion,record,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 } wi
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!"
如您所见,我刚刚定义了一个递归函数,但我犯了一个起初似乎是错误的错误:我忘了通过rec
关键字将函数声明为递归函数
但令我惊讶的是,它编译了!还有更多:如果您添加rec
关键字,那么这是一个语法错误
type MyRecordType =
{ (* ... *) }
with
// syntax error:
static member rec factorial = function
(* ... *)
我在谷歌上搜索了一下,想找个解释,但一无所获。在MSDN文档中,我找不到任何外部提到的rec
关键字,并且截至2010-01-03,它没有提到我正在询问的案例
非静态成员也会发生同样的情况
因此,为什么在记录类型的成员函数上使用
rec
关键字是一个语法错误?“let rec”不是关于定义递归函数,而是在一个环境中定义一个绑定,其中包括当前
要绑定的变量。您也可以使用“let rec”来定义无限列表。通常,您不希望包含绑定
在环境中,因为您可能希望使用相同的名称访问较早的变量
当您定义静态成员函数factorial时,您不是在寻找变量“factorial”的绑定,而是在寻找类型
“MyRecordType”(作为类型定义在环境中),如果它碰巧有一个名为“factorial”的静态成员函数,
它有。所有“成员”函数都隐式地“rec”在它们定义的类型中。有趣。谢谢只是一个问题:我们希望以相同的名称访问早期值的频率是多少(对我来说,这似乎是非常罕见的)?为什么会有人需要呢?是的,我认为我的答案中的“经常”是误导性的。我应该说“有时”。如果需要访问新变量,可以将其重命名为与先前的变量名不冲突的名称。有时重用变量名会更方便。我手边没有任何好的例子,但例如“let tot1=a+b in let tot2=tot1/10 in let tot3=tot2+8 in let tot4=tot3%15 in tot4”如果是“let tot=a+b in let tot=tot/10 in let tot=tot+8 in let tot=tot%15 in tot”,通常会更容易阅读(并进行修改!)。谢谢。如果能在MSDN上的某个地方为RTM记录这一点,那就太好了!正是我想要的