有人可以给出一个超级简单(几行)的例子来基本了解什么类型的家庭可以用于什么类型和他们是什么?
2 + 2类型家庭的例子?
这是一个例子:
{-# Language TypeFamilies, DataKinds, KindSignatures, GADTs, UndecidableInstances #-} data Nat = Z | S Nat type family Plus (x :: Nat) (y :: Nat) :: Nat where Plus 'Z y = y Plus ('S x) y = 'S (Plus x y) data Vec :: Nat -> * -> * where Nil :: Vec 'Z a Cons :: a -> Vec n a -> Vec ('S n) a append :: Vec m a -> Vec n a -> Vec (Plus m n) a append Nil ys = ys append (Cons x xs) ys = Cons x (append xs ys)
请注意,类型系列的许多/最有趣的应用程序需要UndecidableInstances
.你不应该害怕这个扩展.
另一种有用的类型系列是与类相关联的类型.对于一个真正做作的例子,
class Box b where type Elem b :: * elem :: b -> Elem b
一个实例Box
是一种可以从中拉出的东西.例如,
instance Box (Identity x) where type Elem (Identity x) = x elem = runIdentity instance Box Char where type Elem Char = String elem c = [c]
现在elem (Identity 3) = 3
和elem 'x' = "x"
.
您还可以使用类型族来制作奇怪的skolem变量.这最好在尚未发布的GHC 8.0.1中完成,它看起来像
type family Any :: k where {}
Any
是一种奇特的类型.它是无人居住的,它不能(特别)是一个类的实例,它是多重的.事实证明这对某些目的非常有用.这种特殊类型被宣传为安全目标unsafeCoerce
,但Data.Constraint.Forall
使用类似类型的系列用于更有趣的目的.