トラック
/
Gleam
Gleam
/
シラバス
/
ファントム型
ファ

ファントム型 の Gleam

1個の演習

ファントム型について

ファントム型とは、カスタム型の型パラメーターのうち、その型のどの値コンストラクターでも使われていないものです。

少し抽象的ですね。例を見てみましょう。

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

この例では、unit型パラメーターはLengthの値コンストラクターで使われていないので、unitはファントム型です。

この使われていない型パラメーターは無意味に見えるかもしれませんが、Lengthの値の使い方にさらに制約を加えるために使えます。

たとえば、長さを2倍にするdouble関数が考えられます。この関数はどの単位の長さでも動作するので、型パラメーターはジェネリック型変数です。

// 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関数は、他の単位の型パラメーターを持つ長さを受け付けません。ファントム型を使って、正しい単位だけが使われるようにしています。

また、両方に同じ型変数を使うことで、2つの長さの値が同じ単位であることを保証する関数を書くこともできます。

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で編集 リンクは新しいウィンドウまたはタブで開きます

ファントム型を学習する