In fact, you are not using rank-N polymorphism in your code.
foo :: forall a. forall b. forall c. (a -> b) -> c -> Integer -> b
This is a common type of rank-1. He reads: forall a, b and c this function can take a function of type a -> b , a value of type c and Integer and return a value of type b . Therefore, he says that he can execute a function of type Bool -> Integer or a function of type Integer -> Integer . He does not say that a function should be polymorphic in its argument. To say this, you need to use:
foo :: forall b. forall c. (forall a. a -> b) -> c -> Integer -> b
Now you say that the type of the function should be forall a. a -> b forall a. a -> b , where b fixed, but a is the new variable introduced, so the function must be polymorphic in its argument.
source share