軌道
/
Gleam
Gleam
/
課程大綱
/
幽靈型別
幽靈

幽靈型別 在 Gleam

1 個練習

關於 幽靈型別

幽靈型別是自訂型別裡的型別參數,但它沒有用在該型別的任何值建構子上。

這樣講有點抽象,來看個例子吧:

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

在這個例子中,unit型別參數並沒有用在 Length值建構子裡,所以 unit 就是幽靈型別。

這個沒派上用場的型別參數看起來沒什麼用,不過我們可以拿它來對 Length值的使用方式加上更多限制。

舉例來說,我們可以寫一個函式 double,把長度乘以 2。它適用於任何單位的長度,所以這個型別參數是一般的型別變數。

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

我們也可以寫一個函式 add_inch,它只在長度以英寸為單位時才有作用。

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

add_inch函式不會接受其他單位參數的長度,幽靈型別就是用來確保只會用到正確的單位。

也可以寫一個函式,讓兩個長度值使用相同的型別變數,藉此確保它們的單位相同。

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.

幽靈型別也很適合搭配不透明型別使用。如果其他模組無法建構 Length值,我們就能確保這些值不會帶著無效的單位型別被建構出來,而且只有上面定義的函式能搭配它們使用。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 幽靈型別