Lecture 4 — 2017-09-07

Our first interpreter; type classes

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

We saw some examples from the homework and did some refactoring as a class.

Then I introduced us to our first interpreter. We started on the board, defining a grammar like so:

p, q in Prop ::= ⊤ | ⊥ | p ∧ q | p ∨ q | ¬ p | p ⇒ q

p1 = ⊤ ∧ ⊥
p2 = ⊥ ∨ ⊥

We talked about what the propositions p1 and p2 mean… nothing, yet! We had to define an interpretation function, where we interpret elements of Prop as booleans:

2 = { true, false} with standard operations &&, ||, and !

interp : Prop -> 2
interp(⊤) = true
interp(⊥) = false
interp(p ∧ q) = interp(p) && interp(q)
interp(p ∨ q) = interp(p) || interp(q)
interp(¬ p) = !interp(p)
interp(p ⇒ q)  = !interp(p) || interp(q)

Then we did the same in Haskell:

data Prop =
    T
  | F
  | And Prop Prop
  | Or Prop Prop
  | Not Prop
  | Implies Prop Prop

p1 :: Prop
p1 = T `And` F

interp :: Prop -> Bool
interp T = True
interp F = False
interp (And p q) = interp p && interp q
interp (Or p q) = interp p || interp q
interp (Not p) = not $ interp p
interp (Implies p q) = not (interp p) || interp q

We wrote a “pretty printer” for Prop which prints out appropriately parenthesized concrete syntax. It was a little aggressive, though, printing way too many parentheses:

instance Show Prop where
  show T = "T"
  show F = "F"
  show (And a b) = 
    "And (" ++ show a ++ ") (" ++ show b ++ ")"
  show (Or a b) = 
    "Or (" ++ show a ++ ") (" ++ show b ++ ")"  
  show (Implies a b) = 
    "Implies (" ++ show a ++ ") (" ++ show b ++ ")"
  show (Not a) = "Not (" ++ show a ++ ")"

Finally, we talked about how we can manipulte the abstract syntax of Prop in its own right; for example, we can translate away any use of Implies.

compile :: Prop -> Prop
compile (Implies p q) = Not (compile p) `Or` compile q
compile (And p q) = And (compile p) (compile q)
compile (Or p q) = Or (compile p) (compile q)
compile (Not p) = Not $ compile p
compile T = T
compile F = F

Type classes

The last thirty minutes of class, we discussed type classes. We looked at three in particular:

class Show a where
  show :: a -> String

class Eq a where
  (==) :: a -> a -> Bool
  (<>) :: a -> a -> Bool
  x <> y = not (x == y)

data Ordering = LT | EQ | GT

class Eq a => Ord a where
  compare :: a -> a -> Ordering
  compare x y = if x <= y then if y <= x then EQ else LT else GT
  (<=) :: a -> a -> Bool
  x <= y = compare x y <> GT

We also looked at some instances:

instance Show Bool where
  show True = "True"
  show False = "False"

instance Eq a => Eq (Maybe a) where
  Nothing == Nothing   = True
  (Just a) == (Just b) = a == b
  _ == _               = False

We’ll talk more about type classes on Wednesday.