6.8.2. Undecidable (or recursive) superclasses¶
- UndecidableSuperClasses¶
- Since:
8.0.1
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
thence 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 (#10318)
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.