Open RafaelBocquet opened 9 years ago
Thanks for experimenting!
I think I know what is going on here, and it is indeed a bug. For sanity, let's label the variables to A1
with 1
s and those to A2
with 2
s.
GHC tries to infer the kind of A
. It knows from the declaration that A :: kappa1 -> kappa2 -> *
, where kappa1
and kappa2
are unification variables. GHC discovers, looking at A1
, that kappa1 ~ R nu1
and kappa2 ~ R nu1
, where nu1 :: kappa3
. But then, looking at A2
, it discovers that kappa1 ~ R nu2
and kappa2 ~ R nu2
. However, nu1
and nu2
are user-written quantified variables, so GHC refuses to guess that they are the same.
Another key detail here is that GHC can't generalize A
before checking its constructors. If we somehow knew that A :: forall (k :: *) (n :: k). R n -> R n -> *
, then we could just supply differing n1
and n2
parameters to the uses of A
in the types of A1
and A2
. But, GHC can't know A
's kind before checking the constructors, so we're in a bind. This detail is all about so-called "Complete User-Specified Kinds", or CUSKs: if GHC can be sure of a type's exact kind before looking at its constructors, then it will generalize the type before continuing. (This behavior exists in GHC today. See GHC#9200 for much discussion.)
How to solve this? GHC has an internal way of saying that it's OK to unify one user-written quantified variable with another. (These are known as SigTyVar
s.) Perhaps we could make the n
s SigTyVar
s, and then n1
will unify with n2
, and all will be well. But is this always safe? I'm not sure, off the top of my head.
It's possible that we'll need to differentiate arguments from parameters here, much like proper dependently typed languages do in inductive datatype definitions. In other words, require in the data declaration head to separate n
-- which is the same at every use site in the constructors -- from i
and j
(because i
differs).
In any case, great example. Thanks.
I played a bit with this branch of ghc, and got this strange error :