Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type families for dummies

Tags:

haskell

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 example of type families ?

like image 466
jhegedus Avatar asked Feb 09 '23 05:02

jhegedus


1 Answers

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.

like image 98
dfeuer Avatar answered Feb 15 '23 22:02

dfeuer