Rutas
/
Elm
Elm
/
Ejercicios
/
El cofre del tesoro
El cofre del tesoro

El cofre del tesoro

Ejercicio de aprendizaje

Introducción

Genéricos

Introducción

Los genéricos son una funcionalidad del lenguaje que permite reutilizar código. Por ejemplo, no debería importar qué tipo contiene un array para poder calcular su longitud. Por eso la función length usa un parámetro de tipo genérico a en su signatura de tipo.

length : List a -> Int

Parámetros en los tipos

Cuando un tipo es genérico respecto a otro tipo, usamos un nombre en minúscula para ese otro tipo y lo llamamos parámetro de tipo. Ejemplos habituales 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 más de un carácter. La única restricción es que deben ser nombres en minúscula. Por eso, cuando resulta útil, solemos darles nombres descriptivos.

Un tipo puede ser genérico respecto a varios tipos a la vez y, por tanto, tener varios parámetros de tipo. En ese caso, cada tipo independiente recibe un nombre en minúscula distinto. Que sean independientes no impide que acaben siendo el mismo tipo; simplemente permite que sean distintos.

-- 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 habitual.

-- Event is generic over the type a
type alias Event a =
    { at : Time
    , data : a 
    }

Parámetros de tipo en las funciones

Como los tipos pueden ser genéricos, las funciones también. 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 toman 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

Instrucciones

En este ejercicio vas a escribir un TreasureChest genérico (¡y mágico!) para guardar algún tesoro.

1. Define el tipo personalizado genérico TreasureChest

Define un tipo personalizado TreasureChest con una única variante.

La variante debe tener un valor String asociado, que se usará para almacenar la contraseña del cofre del tesoro.

La variante también debe tener un valor genérico asociado, que se usará para almacenar el tesoro. Este valor es genérico para que el tesoro pueda ser cualquier cosa.

2. Define la función getTreasure

Esta función debe recibir dos parámetros:

  • un String (para probar una contraseña)
  • un tipo personalizado genérico TreasureChest

Esta función debe comprobar el intento de contraseña proporcionado contra el String que hay en el 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.

3. Define la función multiplyTreasure

Esta función (de orden superior) debe recibir dos parámetros:

  • una función multiplicadora que recibe un parámetro genérico y devuelve un array del mismo tipo genérico
  • un tipo personalizado genérico TreasureChest, también con el mismo tipo genérico

Esta función debe llamar a la función multiplicadora con el tesoro que hay 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 valor devuelto).

Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Elm Exercism

¿Listo para empezar El cofre del tesoro?

Regístrate en Exercism para aprender y dominar Elm con 28 conceptos110 ejercicios y mentoría humana real, todo gratis.