2010-12-22 18 views
4

Ich bin ein Neuling in der Ocaml. zu schätzen, wenn jemand mir helfen kann zu verstehen, das Material auf Seite 94 des Buches "Entwicklung von Anwendungen mit objektiven Caml vorgestellt".Verständnis einer Imperativ Liste Beispiel in Ocaml

Probleme, die Bedeutung des folgenden Absatzes zu erfassen:

Nur, dass die Bewertung der (itl l) Platz vor der Auswertung von (ihd l) genommen hat, so dass bei der letzten Iteration von imap, die Liste referenziert von l wurde die leere Liste, bevor wir seinen Kopf untersuchten. Die Liste Beispiel ist von nun an definitiv leer, obwohl wir kein Ergebnis erhalten haben

Das imap (function x ! x) Beispiel gibt

Uncaught exception: Failure("hd") 

statt

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

Ich würde denken, dass die

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

icons("one") ((icons("two") ((icon("three")([])))) und zurück

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

Antwort

4

ich das Beispiel in dem Buch werden würde, hat sich die Liste in einem imperativen Stil umgesetzt. Die Funktion itl mutiert die Liste - das heißt, sie ändert die Liste durch Entfernen des ersten Elements. Nach dem Aufruf an itl ist das erste Element für immer verschwunden.

Der schwierige Teil ist die Reihenfolge, in der Argumente icons in der Anweisung ausgeführt werden:

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

In der OCaml spec die Reihenfolge ist nicht angegeben. Als ich das letzte Mal überprüfte, dass der INRIA-Compiler das letzte Argument zuerst bestellt hat, wird (imap f (itl l))vor(f (ihd l)) ausgeführt. Was das bedeutet ist, dass zu der Zeit ihd tatsächlich aufgerufen wird, itl wurde genug aufgerufen, um alle Elemente von l zu entfernen.

Betrachten wir als Beispiel den vorletzten rekursiven Aufruf - l ist nur ["three"]. Sie denken, dass dies dazu führen würde,:

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

die bei Allerdings lassen schauen, was passiert, wenn wir itl nennen zuerst:

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

Als Beispiel versuchen, diesen Code ausgeführt wird:

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

Auf meiner Maschine (OCaml 3.12) bekomme ich diese Ausgabe:

321- : int = 6 
+0

danke für Ihre ausführliche Erklärung – ocamlNewcomer

Verwandte Themen