I declared two functions using the 'forall' quantifier. The first of them has a quantifier with all generic type parameters before the signature. The second has quantifiers in place of the first usage of each generic type parameter.
f :: forall a b c. a -> b -> c -> b -> a
f a _ _ _ = a
g :: forall a. a ->
forall b. b ->
forall c. c -> b -> a
g a _ _ _ = a
I expected that these two functions would be the same (The difference is only in the style of description), but the following two tests showed me that it is not.
w_f :: (forall a b c. a -> b -> c -> b -> a) -> Bool
w_f _ = True
w_g :: (forall a. a ->
forall b. b ->
forall c. c -> b -> a) -> Bool
w_g _ = True
> w_f g
error:
• Couldn't match type: forall b1. b1 -> forall c1. c1 -> b1 -> a
with: b -> c -> b -> a
Expected: a -> b -> c -> b -> a
Actual: a -> forall b. b -> forall c. c -> b -> a
• In the first argument of ‘w_f’, namely ‘g’
In the expression: w_f g
In an equation for ‘it’: it = w_f g
> w_g f
error:
• Couldn't match type: b0 -> c0 -> b0 -> a
with: forall b. b -> forall c. c -> b -> a
Expected: a -> forall b. b -> forall c. c -> b -> a
Actual: a -> b0 -> c0 -> b0 -> a
• In the first argument of ‘w_g’, namely ‘f’
In the expression: w_g f
In an equation for ‘it’: it = w_g f
I created a graphical representation of this case to see what is wrong, but I can't.
Why are they not equivalent? Why can't we move all quantifiers out of the signature like move common multiples out of expression in math? Could somebody please provide an example of types mismatching?

A
forallspecifies a certain kind of function, just like->does.Swapping instances of
->(e.g.A -> B -> CtoB -> A -> C)In your very own words, "the difference is only in the style of description". Yet you're still required to be consistent about that style (i.e. the argument order). You surely aren't confused by the following:
Compare:
Your code is a slightly more elaborate version of the above. The underlying reason for the errors is the same in all three cases, and is very simple. You defined
fandgwith certain argument orders; you had better use them with those argument orders.P.S. The comments note there's
DeepSubsumptionextension that makesw_f gandw_g fcompile, and historically this behavior was the default (hence why you may have absorbed the belief that order shouldn't matter forforall). One reason this is no longer the default is that while there's an obvious conversion fromforall a b. a -> b -> Ctoforall a. a -> forall b. b -> C, this conversion changes definedness.GHC has thus moved towards forcing you to make it explicit when you're changing the
forallorder of a function.