Los genéricos son una característica del lenguaje que permite reutilizar código.
Por ejemplo, no debería importar de qué tipo sean los elementos que contiene una lista para calcular su longitud.
Por eso la función length usa un parámetro de tipo genérico a en su firma de tipo.
length : List a -> Int
Cuando un tipo es genérico sobre otro tipo, usamos un nombre en minúscula para ese otro tipo y lo llamamos parámetro de tipo.
Algunos ejemplos comunes son los tipos personalizados List, Maybe y Result.
-- Maybe is generic over the type a
type Maybe a
= Nothing
| Just a
someString : Maybe String
someString = Just "hello"
someInt : Maybe Int
someInt = Just 42
Una observación importante sobre los nombres de los parámetros de tipo es que pueden tener varios caracteres de longitud. La única restricción es que deben ser nombres en minúscula. Por eso, cuando resulta útil, tendemos a darles nombres descriptivos.
Un tipo puede ser genérico sobre varios otros tipos y, por lo tanto, tener varios parámetros de tipo. En ese caso, cada tipo independiente recibe un nombre en minúscula diferente. El que sean independientes no impide que lleguen a ser el mismo tipo; solo les permite ser diferentes.
-- Result is generic over the types error and value
type Result error value
= Ok value
| Err error
Los alias de tipo de registro también pueden tener parámetros de tipo, aunque es menos común.
-- Event is generic over the type a
type alias Event a =
{ at : Time
, data : a
}
Como los tipos pueden ser genéricos, las funciones también pueden serlo.
Se pueden escribir funciones que manejen tipos genéricos, como Maybe.withDefault.
withDefault : a -> Maybe a -> a
withDefault default maybe =
case maybe of
Just value -> value
Nothing -> default
Las funciones que reciben otras funciones como parámetros se llaman funciones de orden superior, y estas también pueden ser genéricas.
map : (a -> b) -> Maybe a -> Maybe b
map function maybe =
case maybe of
Just value ->
Just (function value)
Nothing ->
Nothing
En este ejercicio vas a escribir un TreasureChest genérico (¡y mágico!) para guardar un tesoro.
Define un tipo personalizado TreasureChest con una sola variante.
La variante debe tener un valor String asociado, que se usará para guardar la contraseña del cofre del tesoro.
La variante también debe tener un valor genérico asociado, que se usará para guardar el tesoro. Este valor es genérico para que el tesoro pueda ser cualquier cosa.
Esta función debe recibir dos parámetros
String (para probar una contraseña)TreasureChest
Esta función debe comparar el intento de contraseña proporcionado con el String del TreasureChest.
La función debe devolver un Maybe.
Si las contraseñas coinciden, devuelve Just con el valor genérico del TreasureChest (¡el tesoro!).
Si las contraseñas no coinciden, devuelve Nothing.
Esta función (de orden superior) debe recibir dos parámetros
TreasureChest, también con el mismo tipo genéricoEsta función debe llamar a la función multiplicadora con el tesoro que está en el cofre.
La función debe devolver un nuevo TreasureChest, con la misma contraseña que el original y con el tesoro multiplicado (el resultado).
Regístrate en Exercism para aprender y dominar Elm con 28 conceptos110 ejercicios y mentoría humana real, todo gratis.