1

我正在阅读 jason 的书,但不太了解以下程序:

let fact2 i =
    let rec loop accum i =
        if i = 0 then 
            accum
        else
            loop (i * accum) (i - 1)
    in
        loop 1
  1. accum 是如何初始化的?
  2. 最后两行(即在循环 1 中)是什么意思?循环有两个参数。为什么这里只传递一个(即循环 1)。

非常感谢!!!

4

3 回答 3

4

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

循环 1 我

整数 1accumloop函数i初始化i并在同一个函数中初始化。

于 2013-09-27T16:43:18.297 回答
3

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

于 2013-09-27T16:45:01.367 回答
1

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

let fact2 =

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

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

在这种特殊情况下,类型的(loop 1)意思int -> int是它接受一个int并返回一个int。的类型意味着它需要一个loop并返回一个。它也可以写得更明确,因为它是右结合的。int -> int -> intintint -> intint -> (int -> int)->

要回答另一个问题,accum通过将 1 传递给 来初始化loop

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

当然,按照其他人的建议添加另一个“i”也可以,但是当其他人忽略它时,您仍然会感到困惑。

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

当然,除了前者只在是一个函数时才会起作用,当然let f x = g x是一样的。let f = gg

于 2013-10-04T21:38:18.300 回答