let a = b in c
can be thought as a syntactic sugar for (\\a -> c) b
, but in a typed setting in general it\'s not the case. For example, in the Milne
You could type (\a -> (a True, a 1)) (\x -> x)
if instead of generalizing only let expressions, you generalized all lambda abstractions. Having done so, one also needs to instantiate type schemas at every use point, not simply at the point where the binder which refers to them is actually used. I'm don't think there's any problem with this actually, outside of the fact that its vastly less efficient. I recall some discussion of this in TAPL, in fact, making similar points.