Parcours
/
Gleam
Gleam
/
Programme
/
Types fantômes
Ty

Types fantômes en Gleam

1 exercice

À propos de Types fantômes

Les types fantômes sont des paramètres de type d'un type personnalisé qui ne sont utilisés dans aucun des constructeurs de valeur de ce type.

C'est un peu abstrait, alors voici un exemple :

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

Dans cet exemple, le paramètre de type unit n'est pas utilisé dans le constructeur de valeur Length, donc unit est un type fantôme.

Ce paramètre de type inutilisé peut sembler inutile, mais il permet d'ajouter d'autres restrictions sur la façon dont les valeurs Length peuvent être utilisées.

Par exemple, on pourrait avoir une fonction double, qui multiplie la longueur. Elle fonctionne avec des longueurs de n'importe quelle unité, donc le paramètre de type est une variable de type générique.

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

On pourrait aussi avoir une fonction add_inch, qui ne fonctionne que si la longueur est en pouces.

// 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 fonction add_inch n'acceptera pas de longueurs avec un autre paramètre d'unité : le type fantôme a permis de garantir que seule l'unité correcte est utilisée.

On peut aussi écrire une fonction qui garantit que deux valeurs de longueur ont la même unité, en utilisant la même variable de type pour les deux.

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.

Les types fantômes s'associent bien aux types opaques. Si les autres modules ne peuvent pas construire de valeurs Length, on peut alors garantir qu'elles ne sont pas construites avec un type d'unité invalide, et que seules les fonctions définies ci-dessus peuvent être utilisées avec elles.

Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet

Apprends Types fantômes