OCaml
Elaborazione lista
Ricerca…
List.Map
List.map ha la firma ('a -> 'b) -> 'a list -> 'b list che in inglese è una funzione che accetta una funzione (chiameremo questa la funzione di mappatura) da un tipo (vale a dire 'a ) ad un altro tipo (cioè 'b ) e una lista del primo tipo. La funzione restituisce un elenco del secondo tipo in cui ogni elemento è il risultato della chiamata della funzione di mappatura su un elemento del primo elenco.
List.map string_of_int [ 1; 2; 3; 4 ]
#- [ "1"; "2"; "3"; "4" ] : string list
I tipi 'a e 'b non devono essere diversi. Ad esempio, possiamo mappare i numeri ai loro quadrati altrettanto facilmente.
let square x = x * x in
List.map square [ 1; 2; 3; 4 ]
#- [ 1; 4; 9; 16 ] : int list
Dati aggregati in un elenco
Le funzioni List.fold_left e List.fold_right sono funzioni di ordine superiore che implementano la logica esterna dell'elenco di aggregazione. L'aggregazione di un elenco, a volte indicato anche come riduzione di un elenco, significa calcolare un valore derivato dall'ispezione sequenziale di tutti gli elementi in tale elenco.
La documentazione del modulo Elenco lo afferma
-
List.fold_left fa [b1; ...; bn]èf (... (f (fa b1) b2) ...) bn. -
List.fold_right f [a1; ...; an] bèf a1 (f a2 (... (f an b) ...)). (Quest'ultima funzione non è coda-ricorsiva.)
In inglese semplice calcolo List.fold_left fa [b1; ...; bn] equivale a scorrere l'elenco [b1; ...; bn] tenendo traccia di un accumulatore inizialmente impostato su a : ogni volta che vediamo un elemento nella lista, usiamo f per aggiornare il valore dell'accumulatore, e quando abbiamo finito, l'accumulatore è il valore finale del nostro calcolo. La funzione List.fold_right è simile.
Ecco alcuni esempi pratici:
Calcola la somma totale di un elenco di numeri
List.fold_left ( + ) 0 lst
Calcola la media di un elenco di float
let average lst =
let (sum, n) =
List.fold_left (fun (sum, n) x -> (sum +. x, n + 1)) (0.0, 0) lst
in
sum /. (float_of_int n)
Riorganizzare l'elaborazione dell'elenco di base
Le funzioni List.fold_left e List.fold_right sono così generali che possono essere utilizzate per implementare quasi tutte le altre funzioni dal modulo elenco:
let list_length lst = (* Alternative implementation to List.length *)
List.fold_left ( + ) 0 lst
let list_filter predicate lst = (* Alternative implementation to List.filter *)
List.fold_right (fun a b -> if predicate a then a :: b else b) lst []
È anche possibile reimplementare la funzione List.iter , ricorda che () è lo stato globale del programma per interpretare questo codice come un ulteriore esempio di aggregazione di elenchi :
let list_iter f lst = (* Alternation implementation to List.iter *)
List.fold_left (fun () b -> f b) () lst
Questi esempi sono pensati per essere materiale didattico, queste implementazioni non hanno virtù sulle funzioni corrispondenti dalla libreria standard.