数据系列用例

时间:2013-01-07 11:59:30

标签: haskell type-families

使用类型同义词系列的好处很明显 - 它是类型级函数。

data 系列并非如此 - 所以我的问题是,数据系列的用例是什么?我应该在哪里使用它?

1 个答案:

答案 0 :(得分:23)

一个好处是数据系列是单射的,与类型系列不同。

如果你有

type family TF a
data family DF a

然后你知道DF a ~ DF b暗示a ~ b,而使用TF,你没有 - 对于任何a你可以确定DF a完全是[a]新类型(就像[b]是与a ~ b不同的类型,当然除非data instance DF Int = DInt Int data instance DF String = DString String class C t where foo :: t Int -> t String instance C DF where -- notice we are using DF without an argument -- notice also that you can write instances for data families at all, -- unlike type families foo (DInt i) = DString (show i) ),而类型系列可以将多种输入类型映射到同一现有类型。

第二个是数据系列可以像任何其他类型的构造函数一样部分应用,而类型系列则不能。

这不是一个特别真实的例子,但是例如,您可以这样做:

DF

基本上,DF adata本身就是真正的,一流的合法类型,就像您使用TF a声明的任何其他类型一样。 data只是一个评估类型的中间形式。

但是,当我想知道数据系列并阅读类似内容时,我认为所有这些都不是很有启发性,或者至少不适合我。

这是我经历的经验法则。每当你发现自己重复你有一个类型族的模式,并且对于每种输入类型,你都要为要映射的类型族声明一个新的vector类型,那么切断中间人并使用数据族就更好了代替。

来自vector库的真实示例。 Vector有几种不同的向量:盒装向量,无盒装向量,基元向量,可存储向量。对于每个MVector类型,存在相应的可变type family Mutable v :: * -> * -> * -- the result type has two type parameters module Data.Vector{.Mutable} where data Vector a = ... data MVector s a = ... type instance Mutable Vector = MVector module Data.Vector.Storable{.Mutable} where data Vector a = ... data MVector s a = ... type instance Mutable Vector = MVector [etc.] 类型(法线向量是不可变的)。所以它看起来像这样:

data family Mutable v :: * -> * -> *

module Data.Vector{.Mutable} where
data Vector a = ...
data instance Mutable Vector s a = ...
type MVector = Mutable Vector

module Data.Vector.Storable{.Mutable} where
data Vector a = ...
data instance Mutable Vector s a = ...
type MVector = Mutable Vector

[etc.]

现在不是那样,我宁愿:

Vector

对不变量进行编码,对于每个Mutable Vector类型,只有一个Vector类型,并且它们之间存在一对一的对应关系。 Mutable Vector的可变版本始终称为Mutable Vector:这是它的名称,它没有其他名称。如果你有一个Vector,你可以得到相应的不可变type family Mutable的类型,因为它就像一个类型参数一样。使用MVector,一旦将其应用于参数,它将评估为未指定的结果类型(可能称为{{1}},但您无法知道),并且您无法向后映射。