Some lambda terms, such as the church number 3: (f x -> (f (f (f x)))), are easily typeable on the simply typed lambda calculus. Others, such as pred, (a b c d e f -> (d (g -> (t -> (t (g e)))) (g -> f) (g -> g))), are known to require more complex systems such as System-F. Some of them aren't typeable on System-F itself, as this zip I posted in another question. As András Kovács observed on the follow-up, that function can be typed in Agda, although the technique he used for doing so isn't trivial.
I have a lot of similarly tricky terms such as nTuple = (k -> (k (b c d -> (b (e -> (c e d)))) (b -> b) (b -> b))), which receives a church number and returns an N-Tuple of that length. I don't know if those terms are typeable. I would like to know:
Some systems seems to ban many "desirable" terms, while others bans less of those. What is the property of a system that determines if it is more accepting or more restricting?
Is there any type system in which arbitrary lambda terms are typeable?
Is there any general technique/algorithm to find the types of those expressions in such system?