有人可以给出一个超级简单(几行)的例子,以便基本了解哪些类型的家族可以使用,以及它们是什么?
2 + 2类型家庭的例子?
答案 0 :(得分:7)
以下是一个例子:
{-# 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
使用类似的类型系列用于更有趣的目的。