La Lista implementazione è interessante da studiare. Ad esempio, la funzione map
potrebbe essere implementato in questo modo:
let rec map f = function
| [] -> []
| a::l -> f a :: map f l
ma è invece implementata in questo modo:
let rec map f = function
| [] -> []
| a::l -> let r = f a in r :: map f l
Qual è la differenza? Eseguire questo:
List.map print_int [1;2;3] ;;
map print_int [1;2;3] ;;
Il primo stampa 123, ma il secondo stampa 321! Poiché la valutazione di f a
potrebbe produrre effetti collaterali, è importante forzare l'ordine corretto. Questo è ciò che fa l'implementazione ufficiale della mappa. Infatti, lo evaluation order of arguments is unspecified in OCaml anche se tutte le implementazioni seguono lo stesso ordine.
Vedere anche lo Optimizing List.map post on the Jane Street blog per considerazioni sulle prestazioni (List.map
è efficiente su elenchi di piccole dimensioni).
fonte
2010-10-21 06:12:18
Pollice in alto! (Qui è il post del blog, ma lo trovo un po 'troppo arcano per un principiante: http://ocaml.janestreet.com/?q=node/71) – gasche
Qualcuno può chiarire la differenza tra la prima e la seconda implementazione ? Quando li eseguo in OCaml e F #, ricevo 123 per entrambi, mai 321. Dato che questa risposta ha 7 anni, forse OCaml e F # sono sostanzialmente cambiati, ma ne dubito? (Non sto usando List.map, sto testando le due funzioni di mappa personalizzate così com'è) – jayphelps
@gasche Qualche idea? –