6.8.2. Undecidable (or recursive) superclasses¶
Allow all superclass constraints, including those that may result in non-termination of the typechecker.
The language extension
UndecidableSuperClasses allows much more flexible
constraints in superclasses.
A class cannot generally have itself as a superclass. So this is illegal
class C a => D a where ... class D a => C a where ...
GHC implements this test conservatively when type functions, or type variables, are involved. For example
type family F a :: Constraint class F a => C a where ...
GHC will complain about this, because you might later add
type instance F Int = C Int
and now we’d be in a superclass loop. Here’s an example involving a type variable
class f (C f) => C f class c => Id c
If we expanded the superclasses of
C Id we’d get first
Id (C Id) and
C Id again.
But superclass constraints like these are sometimes useful, and the conservative check is annoying where no actual recursion is involved.
Moreover genuinely-recursive superclasses are sometimes useful. Here’s a real-life example (%s10318)
class (Frac (Frac a) ~ Frac a, Fractional (Frac a), IntegralDomain (Frac a)) => IntegralDomain a where type Frac a :: Type
Here the superclass cycle does terminate but it’s not entirely straightforward to see that it does.
With the language extension
UndecidableSuperClasses GHC lifts all restrictions
on superclass constraints. If there really is a loop, GHC will only
expand it to finite depth.