代码之家  ›  专栏  ›  技术社区  ›  Bruno Reis

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

  •  23
  • Bruno Reis  · 技术社区  · 15 年前

    我一直相信在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!"
    

    正如您所看到的,我刚刚定义了一个递归函数,但我起初犯了一个错误:我忘记将函数声明为 递归的 借助于 录制 关键字。

    但令我惊讶的是 编译 !还有更多:如果你把 录制 关键字,则是语法错误!

    type MyRecordType =
        { (* ... *) }
        with
            // syntax error:
            static member rec factorial = function
            (* ... *)
    

    我到处寻找解释,但一无所获。在msdn文档中,我找不到任何关于 录制 外关键字 the page about recursive functions 截至2010年1月3日,没有提到我要问的案件。

    非静态成员也会发生同样的事情。

    所以, 为什么使用 收入 记录类型的成员函数的关键字 ?

    2 回复  |  直到 11 年前
        1
  •  17
  •   Sami    15 年前

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

    在定义静态成员函数factorial时,不是为变量factorial寻找绑定,而是为类型 “myrecordtype”(作为类型定义存在于环境中),如果它恰好有一个名为“factorial”的静态成员函数, 它有什么。

        2
  •  17
  •   Brian    14 年前

    所有“member”函数在其定义的类型中都隐式地为“rec”。