GHC “disables” Hindley-Milner in GADT pattern matching, so as to prevent dynamic type information from escaping its scope.
Here's a more extreme example:
import Data.Void
data Idiotic :: * -> * where
Impossible :: !Void -> Idiotic Void
Possible :: a -> Idiotic a
There don't exist any values of type Void, so it isn't possible to ever use the Impossible constructor. Thus, Idiotic a is actually isomorphic to Identity a, IOW to a itself. So, any function that takes an Idiotic value is fully described by just the Possible pattern match. Basically, it always boils down to
sobre :: Idiotic a -> a
sobre (Possible a) = a
which is easy usable in practice.
But as far as the type system is concerned, the other constructor matches just as well, and is in fact required to disable the incomplete pattern warning:
sobre (Impossible a) = {- Here, a::Void -} a
But if the compiler propagated this type information outwards, your function would end up with the completely useless signature
sobre :: Idiotic Void -> Void
G Charin the first place? Deriving types typically happens by first using the most generic type, and subsequently replacing types based on elements in the head and body of the function. - Willem Van Onsemfdoes not impose any restrictions on its input, except that it should beG. The function does not analyzeaorsany further. The fact that inBcan be used forG Charonly is irrelevant for deducingf's type. - yeputonsf (B s)one could be tempted to think that the argument must have typeG Charand not the more generalG a. - mschmidt