Recherche…
Inversion d'une liste de tout type
Pour inverser une liste, il n'est pas important de savoir quel type sont les éléments de la liste, mais uniquement leur ordre. C'est un candidat idéal pour une fonction générique, donc la même fonction d'inversion peut être utilisée quelle que soit la liste transmise.
let rev list =
let rec loop acc = function
| [] -> acc
| head :: tail -> loop (head :: acc) tail
loop [] list
Le code ne fait aucune hypothèse sur les types d'éléments. Le compilateur (ou F # interactif) vous dira que la signature de type de cette fonction est 'T list -> 'T list
Le 'T
vous dit que c'est un type générique sans contraintes. Vous pouvez également voir 'a
au lieu de 'T
- la lettre est sans importance car ce n'est qu'un espace réservé générique . Nous pouvons passer une int list
ou une string list
, et les deux fonctionneront correctement, renvoyant respectivement une int list
ou une string list
.
Par exemple, dans F # interactive:
> 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"]
Mapper une liste dans un type différent
let map f list =
let rec loop acc = function
| [] -> List.rev acc
| head :: tail -> loop (f head :: acc) tail
loop [] list
La signature de cette fonction est ('a -> 'b) -> 'a list -> 'b list
, ce qui est le plus générique possible. Cela n'empêche pas 'a
d'être du même type que d'être 'b
, mais cela leur permet également d'être différent. Ici, vous pouvez voir que le 'a
type qui est le paramètre de la fonction f
doit correspondre au type du paramètre list
. Cette fonction est toujours générique, mais il existe de légères contraintes sur les entrées - si les types ne correspondent pas, il y aura une erreur de compilation.
Exemples:
> 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'