I am a newcomer to the ocaml. appreciate if anyone can help me understand the material presented on page 94 of the开发者_JAVA技巧 book "developing applications with objective caml".
having trouble to grasp the meaning of the following paragraph:
Just that the evaluation of
(itl l)
has taken place before the evaluation of(ihd l)
, so that on the last iteration ofimap
, the list referenced byl
became the empty list before we examined its head. The list example is henceforth definitely empty even though we have not obtained any result
The imap (function x ! x)
example returns
Uncaught exception: Failure("hd")
instead of
- : string ilist = {c=["one"; "two"; "three"]}
I would think that the
else icons (f (ihd l)) (imap f (itl l))`
would become icons("one") ( ( icons("two") ( ( icon("three")([]) ) ) )
and return
- : string ilist = {c=["one"; "two"; "three"]}
I the example in the book, the list has been implemented in an imperative style. The function itl
mutates the list - that is it changes the list by removing the first element. After the call to itl
, the first element is essentially gone forever.
The tricky part is the order in which arguments to icons
are executed in the statement:
else icons (f (ihd l)) (imap f (itl l))
In the OCaml spec the order isn't specified. Last time I checked the INRIA compiler ordered the last argument first, so (imap f (itl l))
is executed before (f (ihd l))
. What this means is that by the time ihd
is actually called, itl
has been called enough times to remove all the elements of l
.
As an example, let's look at the penultimate recursive call - l
is just ["three"]
. You think that this would result in:
icons (f "three") (imap f [])
However let's look at what happens if we call itl
first:
(* l = ["three"] *)
let tail = (itl l) in (* tail = [], l = [] *)
let head = (ihd l) in (* l = [], ihd raises an exception *)
icons head (imap f tail)
As an example, try running this code:
let f x y z = x + y + z
f (print_int 1; 1) (print_int 2; 2) (print_int 3; 3)
On my machine (OCaml 3.12) I get this output:
321- : int = 6
精彩评论