Note [Expanding superclasses]
When we expand superclasses, we use the following algorithm:
transSuperClasses( C tys ) returns the transitive superclasses
of (C tys), not including C itself
For example
class C a b => D a b
class D b a => C a b
Then
transSuperClasses( Ord ty ) = [Eq ty]
transSuperClasses( C ta tb ) = [D tb ta, C tb ta]
Notice that in the recursive-superclass case we include C again at
the end of the chain. One could exclude C in this case, but
the code is more awkward and there seems no good reason to do so.
(However C.f. GHC.Tc.Solver.Dict.mk_strict_superclasses, which /does/
appear to do so.)
The algorithm is expand( so_far, pred ):
1. If pred is not a class constraint, return empty set
Otherwise pred = C ts
2. If C is in so_far, return empty set (breaks loops)
3. Find the immediate superclasses constraints of (C ts)
4. For each such sc_pred, return (sc_pred : expand( so_far+C, D ss )
Notice that
* With normal Haskell-98 classes, the loop-detector will never bite,
so we'll get all the superclasses.
* We need the loop-breaker in case we have UndecidableSuperClasses on
* Since there is only a finite number of distinct classes, expansion
must terminate.
* The loop breaking is a bit conservative. Notably, a tuple class
could contain many times without threatening termination:
(Eq a, (Ord a, Ix a))
And this is try of any class that we can statically guarantee
as non-recursive (in some sense). For now, we just make a special
case for tuples. Something better would be cool.
See also GHC.Tc.TyCl.Utils.checkClassCycles.
************************************************************************
* *
Classifying types
* *
************************************************************************ References 0
This Note does not link to any other.
Referenced by 3
- The superclass story GHC.Tc.Solver.Dict
- GHC.Tc.Solver.Dict call site
- GHC.Tc.Utils.TcType call site