Typed Lambda Calculus |
Type | => | e | Type -> Type |
Term | => | v | λ v: Type. Term | (Term Term) |
For example, we could write the semantics of Ann as λ v: e -> bool. v @ ann, assuming the type of ann is e.
The computation rules for the typed lambda calculus are exactly the same as for the untyped lambda calculus. In fact, you can imagine just erasing the types and evaluating as in the untyped calculus. However, there are many terms of the untyped lambda calculus that cannot be assigned types in such a way to make them legal. For example, λ x. (x x) cannot be assigned a type. While almost all of the terms that we gave names to above can be labeled with types, Y is a prominent exception.
Not surprisingly, the subterm (x x) in Y = λ f. (λx. f (x x)) (λx. f (x x)) cannot be typed. If (x x) is to be legal, then x must have a functional type of the form τ -> σ. But since x is also the argument to the function, x must also have type τ. But there is no (simple) type τ such that τ = τ -> σ.
One might still hope that it is possible to define all computable functions in the typed lambda calculus anyway - you just might have to find an alternative to using the Y combinator, but that would not be the case. This follows from the fact that evaluation of all terms of the typed lambda calculus eventually terminate. [We've seen that is not true of the untyped lambda calculus with (Omega Omega)].
It is easy to show that any effectively listable collection of total computable functions does not include all effectively computable functions. (Proof: If f0, f1, ..., is a list of effectively computable total functions, define f(n) = fn(n) + 1, which is both effectively computable and different from all of the fi's in the list.
Note: ML escapes this restriction because not all functions definable in ML are total. This is because there are primitive fixed point operators in each function type.
Typed Lambda Calculus |