Tracks
/
Gleam
Gleam
/
Lehrplan
/
Phantomtypen
Ph

Phantomtypen in Gleam

1 Übung

Über Phantomtypen

Phantomtypen sind Typparameter eines eigenen Typs, die in keinem der Wertkonstruktoren dieses Typs verwendet werden.

Das ist etwas abstrakt, deshalb hier ein Beispiel:

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

In diesem Beispiel wird der Typparameter unit nicht im Wertkonstruktor Length verwendet, also ist unit ein Phantomtyp.

Dieser ungenutzte Typparameter mag nutzlos erscheinen, aber er kann genutzt werden, um weitere Einschränkungen dafür festzulegen, wie Length-Werte verwendet werden können.

Zum Beispiel könnten wir eine Funktion double haben, die die Länge multipliziert. Sie funktioniert mit Längen jeder Einheit, also ist der Typparameter eine generische Typvariable.

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

Wir könnten auch eine Funktion add_inch haben, die nur funktioniert, wenn die Länge in Zoll angegeben ist.

// 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)
}

Die Funktion add_inch akzeptiert keine Längen mit einem anderen Einheitenparameter, der Phantomtyp wurde verwendet, um sicherzustellen, dass nur die richtige Einheit verwendet wird.

Du kannst auch eine Funktion schreiben, die sicherstellt, dass zwei Längenwerte dieselbe Einheit haben, indem du für beide dieselbe Typvariable verwendest.

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.

Phantomtypen lassen sich gut mit opaken Typen kombinieren. Wenn andere Module keine Length-Werte konstruieren können, können wir sicherstellen, dass sie nicht mit einem ungültigen Einheitentyp konstruiert werden und dass nur die oben definierten Funktionen mit ihnen verwendet werden können.

Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab

Lerne Phantomtypen