Ricerca…
Inversione di un elenco di qualsiasi tipo
Per invertire una lista, non è importante che tipo siano gli elementi della lista, solo in che ordine si trovano. Questo è un candidato perfetto per una funzione generica, quindi la stessa funzione di reverseal può essere usata indipendentemente da quale lista viene passata.
let rev list =
let rec loop acc = function
| [] -> acc
| head :: tail -> loop (head :: acc) tail
loop [] list
Il codice non fa ipotesi sui tipi di elementi. Il compilatore (o F # interattivo) ti dirà che la firma del tipo di questa funzione è 'T list -> 'T list
Il 'T
ti dice che è un tipo generico senza vincoli. Puoi anche vedere 'a
anziché 'T
- la lettera non è importante perché è solo un segnaposto generico . Possiamo passare un int list
o una string list
, ed entrambe funzioneranno correttamente, restituendo rispettivamente un int list
o una string list
.
Ad esempio, in F # interattivo:
> let rev list = ...
val it : 'T list -> 'T list
> rev [1; 2; 3; 4];;
val it : int list = [4; 3; 2; 1]
> rev ["one", "two", "three"];;
val it : string list = ["three", "two", "one"]
Mappatura di un elenco in un tipo diverso
let map f list =
let rec loop acc = function
| [] -> List.rev acc
| head :: tail -> loop (f head :: acc) tail
loop [] list
La firma di questa funzione è ('a -> 'b) -> 'a list -> 'b list
, che è il più generico possibile. Ciò non impedisce ad 'a
di essere dello stesso tipo di essere 'b
, ma permette anche che siano diversi. Qui puoi vedere che 'a
tipo che è il parametro della funzione f
deve corrispondere al tipo del parametro list
. Questa funzione è ancora generica, ma ci sono alcuni lievi vincoli sugli input - se i tipi non corrispondono, ci sarà un errore di compilazione.
Esempi:
> let map f list = ...
val it : ('a -> 'b) -> 'a list -> 'b list
> map (fun x -> float x * 1.5) [1; 2; 3; 4];;
val it : float list = [1.5; 3.0; 4.5; 6.0]
> map (sprintf "abc%.1f") [1.5; 3.0; 4.5; 6.0];;
val it : string list = ["abc1.5"; "abc3.0"; "abc4.5"; "abc6.0"]
> map (fun x -> x + 1) [1.0; 2.0; 3.0];;
error FS0001: The type 'float' does not match the type 'int'