Die Liste Implementierung ist interessant zu studieren. Zum Beispiel könnte die map
Funktion wie folgt umgesetzt werden:
let rec map f = function
| [] -> []
| a::l -> f a :: map f l
sondern wird wie folgt umgesetzt:
let rec map f = function
| [] -> []
| a::l -> let r = f a in r :: map f l
Was ist der Unterschied? Führen Sie dies aus:
List.map print_int [1;2;3] ;;
map print_int [1;2;3] ;;
Das erste druckt 123, aber das zweite druckt 321! Da die Auswertung von f a
Nebenwirkungen hervorrufen kann, ist es wichtig, die richtige Reihenfolge zu erzwingen. Dies ist, was die offizielle Kartenimplementierung tut. In der Tat, die evaluation order of arguments is unspecified in OCaml auch wenn alle Implementierungen die gleiche Reihenfolge folgen.
Siehe auch die Optimizing List.map post on the Jane Street blog für Überlegungen zur Leistung (List.map
ist effizient auf kleinen Listen).
Daumen hoch! (Hier ist der Blogpost, aber ich finde es ein bisschen zu geheimnisvoll für einen Anfänger: http://ocaml.janestreet.com/?q=node/71) – gasche
Kann jemand den Unterschied zwischen der ersten und zweiten Implementierungen klären ? Wenn ich sie in OCaml und F # führe, erhalte ich 123 für beide, nie 321. Da diese Antwort 7 Jahre alt ist, haben sich OCaml und F # grundlegend geändert, aber ich bezweifle es? (Ich verwende nicht List.map, ich teste die beiden benutzerdefinierten Kartenfunktionen wie sie ist) – jayphelps
@gasche Irgendeine Idee? –