summaryrefslogtreecommitdiff
path: root/docs/users_guide/exts/undecidable_super_classes.rst
blob: e6f33e232d836113d6ed8d0e3d7ff344d30159ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Undecidable (or recursive) superclasses
---------------------------------------

.. extension:: UndecidableSuperClasses
    :shortdesc: Allow all superclass constraints, including those that may
        result in non-termination of the typechecker.

    :since: 8.0.1

    Allow all superclass constraints, including those that may result in
    non-termination of the typechecker.

The language extension :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 genuninely-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 :extension:`UndecidableSuperClasses` GHC lifts all restrictions
on superclass constraints. If there really *is* a loop, GHC will only
expand it to finite depth.