Buscar..
Reversión de una lista de cualquier tipo.
Para revertir una lista, no es importante el tipo de elementos de la lista, solo el orden en el que están. Este es un candidato perfecto para una función genérica, por lo que se puede usar la misma función reverseal sin importar qué lista se pase.
let rev list =
let rec loop acc = function
| [] -> acc
| head :: tail -> loop (head :: acc) tail
loop [] list
El código no hace suposiciones sobre los tipos de los elementos. El compilador (o F # interactivo) le dirá que la firma de tipo de esta función es 'T list -> 'T list
. La 'T
le dice que es un tipo genérico sin restricciones. También puede ver 'a
lugar de 'T
: la letra no es importante porque es solo un marcador de posición genérico . Podemos pasar una int list
o una string list
, y ambas funcionarán correctamente, devolviendo una int list
o una string list
respectivamente.
Por ejemplo, en F # interactivo:
> 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"]
Mapeo de una lista en un tipo diferente
let map f list =
let rec loop acc = function
| [] -> List.rev acc
| head :: tail -> loop (f head :: acc) tail
loop [] list
La firma de esta función es ('a -> 'b) -> 'a list -> 'b list
, que es la más genérica que puede ser. Esto no impide que 'a
a sea del mismo tipo que 'b
, pero también les permite ser diferentes. Aquí puede ver que 'a
tipo que es el parámetro de la función f
debe coincidir con el tipo del parámetro de list
. Esta función aún es genérica, pero hay algunas restricciones leves en las entradas: si los tipos no coinciden, habrá un error de compilación.
Ejemplos:
> 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'