When we enable PolyKinds, do we know that f a ~ g b implies f ~ g and a ~ b?
If a type-level application has different kinds, then the two types can not be shown to be equal. Here is evidence:
GHC.Prim> () :: ((Any :: * -> *) Any) ~ ((Any :: (* -> *) -> *) Any) => ()
:6:1:
Couldn't match kind ‘*’ with ‘* -> *’
Expected type: Any Any
Actual type: Any Any
In the expression:
() :: ((Any :: * -> *) Any) ~ ((Any :: (* -> *) -> *) Any) => ()
In an equation for ‘it’:
it
= () :: ((Any :: * -> *) Any) ~ ((Any :: (* -> *) -> *) Any) => ()
:6:7:
Couldn't match kind ‘*’ with ‘* -> *’
Expected type: Any Any
Actual type: Any Any
In the ambiguity check for: Any Any ~ Any Any => ()
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In an expression type signature:
((Any :: * -> *) Any) ~ ((Any :: (* -> *) -> *) Any) => ()
In the expression:
() :: ((Any :: * -> *) Any) ~ ((Any :: (* -> *) -> *) Any) => ()
(Even turning on the suggested AllowAmbiguousTypes extension gives the same type-checking error -- just without the suggestion.)
Therefore, if two types can be shown to be equal, then type-level applications in the same structural position on the two sides of the equality have the same kind.
If you wish for proof instead of evidence, one would need to write down a careful inductive proof about the system described in Type Checking with Open Type Functions. Inspection of Figure 3 suggests to me that the invariant, "all type applications in ~'s have the same kind on both sides of the ~" is preserved, though neither I nor the paper prove this carefully, so there is some chance it is not so.