Type families for dummies

前端 未结 1 656
无人及你
无人及你 2021-01-14 07:12

Could someone give a super simple (few line) example to get a basic understanding about what type families can be used for and what are they ?

The 2+2 kind of exampl

相关标签:
1条回答
  • 2021-01-14 07:42

    Here's an example:

    {-# 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)
    

    Note that many/most interesting applications of type families require UndecidableInstances. You should not be scared of this extension.


    Another useful sort of type family is one associated with a class. For a really contrived example,

    class Box b where
      type Elem b :: *
      elem :: b -> Elem b
    

    An instance of Box is a type that something can be pulled out of. For instance,

    instance Box (Identity x) where
      type Elem (Identity x) = x
      elem = runIdentity
    
    instance Box Char where
      type Elem Char = String
      elem c = [c]
    

    Now elem (Identity 3) = 3 and elem 'x' = "x".

    You can also use type families to make weird skolem variables. This is best done in the as-yet-unreleased GHC 8.0.1, where it will look like

    type family Any :: k where {}
    

    Any is a peculiar type. It's uninhabited, it can't be (specifically) an instance of a class, and it's poly-kinded. This turns out to be really useful for certain purposes. This particular type is advertised as a safe target for unsafeCoerce, but Data.Constraint.Forall uses similar type families for more interesting purposes.

    0 讨论(0)
提交回复
热议问题