Dependent Types

  • General: Dependent types are type-valued functions.
  • Specific: Functions that send terms to types.

Motivations

Vectors

Vector :: Nat -> *
init : Pi n : Nat . data -> Vector n
cons : Pi n : Nat . data -> Vector n -> Vector (n + 1)

Here, the $\Pi x : S.T$, or Pi x : S. T, is called "Pi type". This type generalizes the arrow type of the simply typed lambda-calculus. It is the type of functions which map elements $s:S$ to elements of $[x \mapsto s]T$.

Note the safe first:

first : Pi n : Nat . Vector (n + 1) -> data

We can use $\Pi x: S.T$ to generalize the function space $S \rightarrow T$, if x doesn't appear free in $T$.

Here, the stressing of being free is essentially saying that $T$'s formation has no relationship with $x:S$. Those, it degenerates to the simply typed case.

Another example

sprintf : Pi f : Format. Data(f) -> String
-- in which
Data([])        = Unit
Data("%d"::cs)  = Nat * Data(cs)
Data("%s"::cs)  = String * Data(cs)
-- ...

Curry-Howard correspondence

For example, $((A \rightarrow B) \rightarrow A) \rightarrow (A \rightarrow B) \rightarrow B$ is valid in constructive logic, and at the same time, is inhabited by term $\lambda f .\lambda u . u(f \, u)$.

If propositions are types, then proofs are terms.

    A =====> B
    |        |
   Prf A -> Prf B

CH-corres allows one to freely mix propositions and PL types.

ith : Pi n : Nat . Pi l : Nat . Lt(l, n) -> Vector(n) -> T

Here, Lt(l, n) is the proposition asserting that l is less then n.

Another example about the type of binary, associative operations on some type T:

Sigma m : T -> T -> T.
    Pi x : T.
        Pi y : T.
            Pi z : T.
                Id (m(x, m(y, z))) (m(m(x, y), z))

Here Sigma m : A . B(x) is the type of pairs where a : A and b: B(a).

Higher-Order Abstract Syntax

Ty :: *
Tm :: Ty -> *
base : Ty
arrow : Ty -> Ty -> Ty
app : Pi A : Ty . Pi B : Ty . Tm (arrow A B) -> Tm A -> Tm B
lam : Pi A : Ty . Pi B : Ty . (Tm A -> Tm B) -> Tm (arrow A B)
-- id on type A
idA = lam A A (\x : Tm A.x)

-- Church 2
two = \A:Ty. lam A (arrow (arrow A A) A)
        (\x:Tm A.lam _ _
                (\f:Tm (arrow A A).
                    app _ _ f (app _ _ f x)))

Pure First-Order Dependent Types

Kinds allow us to distinguish between proper types of kind * and type families if kind Pi x : T. K.

Problem introduces by type equivalence:

  • Whether or not typechecking is decidable

Martin-Löf: definitional equality.