了解Ocaml中的命令列表示例

时间:2010-12-22 05:11:24

标签: ocaml

我是ocaml的新手。 感谢任何人都可以帮助我理解 本书第94页上的材料 “以客观的方式开发应用程序”。

无法掌握以下段落的含义:

  

只是(itl l)的评价发生在之前   评估(ihd l),以便在imap的最后一次迭代中,l引用的列表   在我们检查它的头之前,它成了空名单。列表示例从此开始   即使我们没有获得任何结果,也绝对是空的

imap (function x ! x)示例返回

Uncaught exception: Failure("hd")

而不是

- : string ilist = {c=["one"; "two"; "three"]}

我会认为

else icons (f (ihd l)) (imap f (itl l))`

将成为icons("one") ( ( icons("two") ( ( icon("three")([]) ) ) ) 并返回

- : string ilist = {c=["one"; "two"; "three"]}

1 个答案:

答案 0 :(得分:4)

我在书中的例子中,列表已经以命令式的方式实现。函数itl改变列表 - 即通过删除第一个元素来更改列表。在调用itl之后,第一个元素基本上就永远消失了。

棘手的部分是icons的参数在语句中执行的顺序:

else icons (f (ihd l)) (imap f (itl l))

在OCaml规范中未指定顺序。上次我检查INRIA编译器首先命令最后一个参数,所以(imap f (itl l))(f (ihd l))之前执行。这意味着,在实际调用ihd时,itl已被调用足够多次以删除l的所有元素。

举个例子,让我们看一下倒数第二个递归调用 - l只是["three"]。你认为这会导致:

icons (f "three") (imap f [])

但是,让我们来看看如果我们先调用itl会发生什么:

(* l = ["three"] *)
let tail = (itl l) in (* tail = [], l = [] *)
let head = (ihd l) in (* l = [], ihd raises an exception *)
icons head (imap f tail)

例如,尝试运行此代码:

let f x y z = x + y + z
f (print_int 1; 1) (print_int 2; 2) (print_int 3; 3)

在我的机器上(OCaml 3.12)我得到了这个输出:

321- : int = 6