Tracks
/
Gleam
Gleam
/
Ejercicios
/
Tienda de calcomanías
Tienda de calcomanías

Tienda de calcomanías

Ejercicio de aprendizaje

Introducción

Tipos fantasma

Los tipos fantasma son parámetros de tipo de un tipo personalizado que no se usan en ninguno de los constructores de valor de ese tipo.

Eso es un poco abstracto, así que aquí tienes un ejemplo:

pub type Length(unit) {
  Length(amount: Float)
}

En este ejemplo, el parámetro de tipo unit no se usa en el constructor de valor Length, así que unit es un tipo fantasma.

Este parámetro de tipo sin usar puede parecer inútil, pero se puede usar para agregar más restricciones sobre cómo se pueden usar los valores Length.

Por ejemplo, podríamos tener una función double, que multiplica la longitud. Funciona con longitudes de cualquier unidad, así que el parámetro de tipo es una variable de tipo genérica.

// This function accepts all Length values
pub fn double(length: Length(unit)) -> Length(unit) {
  Length(length.amount *. 2.0)
}

También podríamos tener una función add_inch, que solo funciona si la longitud está en pulgadas.

// A unit type for inches. It is never constructed so we don't
// define any constructors for it.
pub type Inches

pub fn add_inch(length: Length(Inches)) -> Length(Inches) {
  Length(length.amount +. 1.0)
}

La función add_inch no aceptará longitudes de ningún otro parámetro de unidad; el tipo fantasma se usó para asegurar que solo se use la unidad correcta.

También se puede escribir una función para asegurar que dos valores de longitud sean de la misma unidad, usando la misma variable de tipo para ambos.

pub fn add(a: Length(unit), b: Length(unit)) -> Length(unit) {
  Length(a.amount +. b.amount)
}
let two_meters: Length(Meters) = Length(2.0)
let two_inches: Length(Inches) = Length(2.0)

add(two_meters, two_meters)
// -> Length(4.0): Length(Meters)

add(two_meters, two_inches)
// Type error! The unit type parameters do not match.

Los tipos fantasma pueden funcionar bien con los tipos opacos. Si otros módulos no pueden construir valores Length, entonces podemos asegurarnos de que no se construyan con un tipo de unidad inválido, y de que solo se puedan usar con ellos las funciones definidas arriba.

Instrucciones

Lucy tiene una tienda de calcomanías en línea, donde vende lindas calcomanías con los lenguajes de programación favoritos de todos. Personas de todo el mundo compran sus calcomanías, y está teniendo algunos problemas para lidiar con todas las distintas monedas.

Crea un programa que Lucy pueda usar para calcular precios y asegurarse de que siempre esté usando la moneda correcta.

1. Define los tipos Usd, Eur y Jpy

Estos tipos se usan para representar las distintas monedas con las que los clientes de Lucy compran sus calcomanías.

Se deben usar como tipos fantasma y no necesitan tener ningún constructor.

2. Define el tipo Money.

El tipo Money debe tener un campo de tipo Int para la cantidad de dinero, un parámetro de tipo fantasma para la moneda, y debe ser un tipo opaco.

3. Define las funciones dollar, euro y yen

Define las funciones dollar, euro y yen, que toman un argumento de tipo Int y devuelven un valor de tipo Money con la moneda correcta.

4. Define la función total

Define la función total, que toma un array de valores Money y devuelve la cantidad total de dinero que hay en el array.

total([euro(120), euro(200), euro(145)])
// -> euro(465)
Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
Gleam Exercism

¿Todo listo para empezar Tienda de calcomanías?

Regístrate en Exercism para aprender y dominar Gleam con 33 conceptos122 ejercicios y mentoría humana real, todo gratis.