Tracce
/
Gleam
Gleam
/
Programma
/
Tipi fantasma
Ti

Tipi fantasma in Gleam

1 esercizio

Informazioni su Tipi fantasma

I tipi fantasma sono parametri di tipo di un tipo personalizzato che non vengono usati in nessuno dei costruttori di valore di quel tipo.

È un po' astratto, quindi ecco un esempio:

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

In questo esempio il parametro di tipo unit non viene usato nel costruttore di valore Length, quindi unit è un tipo fantasma.

Questo parametro di tipo inutilizzato può sembrare inutile, ma può servire ad aggiungere ulteriori restrizioni su come si possono usare i valori di Length.

Per esempio, potremmo avere una funzione double, che moltiplica la lunghezza. Funziona con lunghezze di qualsiasi unità, quindi il parametro di tipo è una variabile di tipo generica.

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

Potremmo anche avere una funzione add_inch, che funziona solo se la lunghezza è in pollici.

// 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 funzione add_inch non accetterà lunghezze con qualsiasi altro parametro di unità: il tipo fantasma è stato usato per assicurarsi che venga usata solo l'unità corretta.

Si può anche scrivere una funzione che garantisca che due valori di lunghezza siano della stessa unità, usando la stessa variabile di tipo per entrambi.

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.

I tipi fantasma possono funzionare bene con i tipi opachi. Se gli altri moduli non possono costruire valori di Length, allora possiamo assicurarci che non vengano costruiti con un tipo di unità non valido e che con essi si possano usare solo le funzioni definite sopra.

Modifica tramite GitHub Il collegamento si apre in una nuova finestra o scheda

Impara Tipi fantasma