tail递归执行阶乘函数

时间:2013-09-27 16:15:22

标签: ocaml tail-recursion factorial

我正在阅读杰森的这本书,并且不太了解以下程序:

let fact2 i =
    let rec loop accum i =
        if i = 0 then 
            accum
        else
            loop (i * accum) (i - 1)
    in
        loop 1
  1. 如何初始化累积?
  2. 最后两行(即第1循环)的含义是什么?循环有两个参数。为什么只有一个传递到这里(即循环1)。
  3. 非常感谢!!!

3 个答案:

答案 0 :(得分:4)

我认为这是实施中的错误。最后一行应该是

  

循环1 i

整数1从accum函数初始化loopi在同一函数中初始化i

答案 1 :(得分:3)

请注意,以let rec loop accum i开头的行定义了函数。因此,在调用函数时初始化accum。这发生在最后一行。正如Kakadu指出的那样,你的帖子中有一个转录错误。最后一行应该说loop 1 i(实质上)将accum初始化为1。

答案 2 :(得分:1)

我认为你在第一行有一个额外的“我”。这使得fact2采取了一个从未使用过的额外参数。相反它应该是:

let fact2 =

表示“循环1”的最后一行通常称为部分应用程序。

Ocaml通常使用curried函数,因此另一种思考方式是loop实际上接受一个参数并返回一个函数,该函数又接受另一个参数并返回一个int。

在此特定情况下,(loop 1)的类型为int -> int,表示需要int并返回intloop的类型为int -> int -> int,表示需要int并返回int -> int。它也可以更明确地编写为int -> (int -> int),因为->是右关联的。

要回答其他问题,请将accum传递给loop进行初始化。

以下是有关currying的更多信息:http://en.wikipedia.org/wiki/Currying

当然,正如其他人所暗示的那样添加另一个“我”也会起作用,但是当其他人将其删除时,你仍会感到困惑。

let f x y = ...视为等同于let f = fun x -> fun y -> ...

可能会有所帮助

当然let f x = g xlet f = g相同,但前者仅在g为函数时才有效。