Sök…
Omvändning av en lista av vilken typ som helst
För att vända en lista är det inte viktigt vilken typ av listelementen är, bara vilken ordning de är i. Detta är en perfekt kandidat för en generisk funktion, så samma omvänd funktion kan användas oavsett vilken lista som ges.
let rev list =
let rec loop acc = function
| [] -> acc
| head :: tail -> loop (head :: acc) tail
loop [] list
Koden gör inga antaganden om elementens typer. Kompilatorn (eller F # interaktiv) berättar att typsignaturen för denna funktion är 'T list -> 'T list
. 'T
säger att det är en generisk typ utan begränsningar. Du kanske också ser 'a
istället för 'T
- brevet är obetydligt eftersom det bara är en generisk platshållare. Vi kan passera en int list
eller en string list
, och båda kommer att fungera framgångsrikt, returnera en int list
respektive en string list
.
Till exempel i F # interaktiv:
> 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"]
Kartlägga en lista till en annan typ
let map f list =
let rec loop acc = function
| [] -> List.rev acc
| head :: tail -> loop (f head :: acc) tail
loop [] list
Signaturen för denna funktion är ('a -> 'b) -> 'a list -> 'b list
, som är den mest generiska den kan vara. Detta förhindrar inte att 'a
är av samma typ som att vara 'b
, men det tillåter dem också att vara annorlunda. Här kan du se att 'a
typ som är den parameter till funktionen f
måste matcha typen av list
parameter. Den här funktionen är fortfarande generisk, men det finns vissa små begränsningar på ingångarna - om typerna inte matchar kommer det att finnas ett kompileringsfel.
Exempel:
> 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'