Lecture 12 — 2015-10-12

More types

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

I put up a midterm evaluation form. Please fill it out if you haven’t yet—if you don’t tell me what’s not working, I can’t fix it.

Intrinsic vs. extrinsic types

We picked up where we left off, looking at the typing relation for the lambda calculus.

The standard format treats types as extrinsic, a separate layer on top of terms. The corresponding type system defines terms and types in separate layers:

e ::= x | e1 e2 | \x. e

t ::= a | t1 -> t2

There are two kinds of types: type constants a and arrow or function types t1 -> t2. The type constant a is a placeholder—no lambda calculus term will ever have the type a, because all lambda calculus terms are functions. If we didn’t have type constants, though, we wouldn’t be able to form any finite types, since arrow types are made up of two other types. Type constants are convenient trick to get a “base case”.

The extrinsic typing rules are as follows:

G ::= empty | G,x:t

(empty)(x) = undefined
(G,x:t)(x) = t
(G,y:t)(x) = G(t)

G(x) = t
---------- Var
G |- x : t

G |- e1 : t1 -> t2    G |- e2 : t1
---------------------------------- App 
G |- e1 e2 : t2

G,x:t1 |- e : t2
--------------------- Lam 
G |- \x. e : t1 -> t2

We did some derivations on the board, but the extrinsic form is somewhat frustrating: whenever we apply Lam, we have to guess the argument type. This can be hard!

The intrinsic approach to the lambda calculus does away with this problem by simply annotating lambdas with their intended argument type, defining terms in terms of types.

e ::= x | e1 e2 | \x:t. e
t ::= a | t1 -> t2

G(x) = t
---------- Var
G |- x : t

G |- e1 : t1 -> t2    G |- e2 : t1
---------------------------------- App 
G |- e1 e2 : t2

G,x:t1 |- e : t2
------------------------ Lam 
G |- \x:t1. e : t1 -> t2

The intrinsic system is unambiguous: \x:a. a is the identity function on as, with type a -> a; \x:(b->b). x is the identity function on b->bs, with type (b->b) -> (b->b), i.e., (b->b) -> b -> b. The extrinsic system can of course type the term \x. x at either of these types.