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 utilizan en ninguno de los constructores de valores de ese tipo.

Esto 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 utiliza en el constructor de valores Length, por lo que unit es un tipo fantasma.

Puede que este parámetro de tipo sin usar parezca inútil, pero sirve para añadir más restricciones a 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 con ningún otro parámetro de unidad; el tipo fantasma se ha usado para garantizar que solo se utilice la unidad correcta.

También se puede escribir una función que garantice que dos valores de longitud son 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 se combinan bien con los tipos opacos. Si otros módulos no pueden construir valores Length, podemos garantizar que no se construyan con un tipo de unidad no válido y que solo se puedan usar con ellos las funciones definidas anteriormente.

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

Aprende Tipos fantasma