Lecture 14 — 2015-10-21

Extending type systems

This lecture is written in literate Haskell; you can download the raw source.

Some course logistics: next week is the review and the midterm. Bring questions on Monday, or else we’ll just sit there and stare at each other.

There’s a new homework resubmission policy, described in the syllabus.

In class, we went over the typing rules for sums and then jumped into recursive types. I went a little fast and there wasn’t time to fully cover them, so they won’t be on the midterm. (They will be on the homework!)

The code below is an embellishment of the code I showed briefly in class.

import Prelude hiding (map,head,tail)

newtype Mu f = Fold { unFold :: f (Mu f) }

data ListF a f = Nil | Cons a f
type List a = Mu (ListF a)

head :: List a -> a
head l = 
  case unFold l of
    Nil -> error "no good"
    Cons x _ -> x

tail :: List a -> List a
tail l = 
  case unFold l of
    Nil -> error "no good"
    Cons _ xs -> xs

nil :: List a
nil = Fold Nil

cons :: a -> List a -> List a
cons x xs = Fold (Cons x xs)

map :: (a -> b) -> List a -> List b
map f l = 
  case unFold l of
    Nil -> nil
    Cons x xs -> cons (f x) (map f xs)

append :: List a -> List a -> List a
append l1 l2 = 
  case unFold l1 of
    Nil -> l2
    Cons x xs -> cons x (append xs l2)

data TreeF a x = Leaf a | Node a x x
type Tree a = Mu (TreeF a)

preOrder :: Tree Int -> List Int
preOrder (Fold (Leaf n)) = cons n nil
preOrder (Fold (Node n l r)) = preOrder l `append` cons n nil `append` preOrder r