Tracks
/
Gleam
Gleam
/
Temario
/
Tipos fantasma
Ti

Tipos fantasma en Gleam

1 ejercicio

Acerca de Tipos fantasma

Los tipos fantasma son parámetros de tipo de un tipo personalizado que no se usan en ninguno de los constructores de valores 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 valores Length, así que unit es un tipo fantasma.

Este parámetro de tipo sin usar puede parecer inútil, pero sirve para agregar más restricciones sobre cómo se pueden usar los valores de 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 con ningún otro parámetro de unidad; el tipo fantasma se ha usado para asegurar que solo se use la unidad correcta.

También se puede escribir una función que asegure 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 de Length, entonces podemos asegurar que no se construyan con un tipo de unidad inválido y que solo se puedan usar con ellos las funciones definidas arriba.

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

Aprende Tipos fantasma