Type Systems #4: STLC is not enough!


(This is part 4 in a series on type systems. You can find part 3 here .)

I have brought a fresh lambda term for you, but I forgot to type it! What do you think its type should be?

Question 1:
apply = λf. (λx. f x)

🤔

Not so easy, is it. It feels like applys type should depend on whatever function you pass in.. if you pass in plusOne, then apply plusOne should be a function Int → Int. But if you pass in not, then apply not should be a function Boolean → Boolean.

Or in other words, we would really like apply to be generic.

But if we recall the rules of simply typed lambda calculus, then we see that we have no way to express this genericity. Function parameters in STLC must be of a type that’s allowed by the language, and that’s either a base type (we chose Int, Boolean, String previously), or a function type like Int → Int.

That is to say, STLC will allow us to define concrete instances of apply, like these:

applyInt = λf: (IntInt). λx: Int. f x
applyBool = λf: (BooleanBoolean). λx: Boolean. f x

But we can’t define a generic apply that works for all types. This is the hard limit of STLC, and we will need to move to a more powerful type system to express these kinds of functions.

(This is part 4 in a series on type systems. You can find part 5 here .)