幻影

幻影类型 属于 Gleam

1 个练习

关于 幻影类型

幻影类型是自定义类型的类型参数,但在该类型的任何值构造器中都没有用到。

这有点抽象,来看一个例子:

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

在这个例子中,unit类型参数没有用在Length值构造器中,所以unit是一个幻影类型。

这个未使用的类型参数可能看起来没什么用,但可以用来进一步限制Length值的使用方式。

例如,我们可以有一个函数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函数不会接受其他单位参数的长度,这里借助幻影类型来确保只使用正确的单位。

也可以写一个函数,通过为两个长度值使用同一个类型变量,来确保它们具有相同的单位。

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 编辑 该链接会在新窗口或标签页中打开

学习 幻影类型