summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2015-12-09 17:38:41 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2015-12-09 17:38:41 +0000
commitb6a71da37ad783bccee2739593b9692aa94a078d (patch)
tree9e817719c6c1b47902dabc5792bfee5b6e618caf
parent643397a09f6e08a97dc104db3b1fd3cb8fa06770 (diff)
downloadhaskell-wip/T11067.tar.gz
Documentationwip/T11067
-rw-r--r--docs/users_guide/glasgow_exts.rst37
1 files changed, 37 insertions, 0 deletions
diff --git a/docs/users_guide/glasgow_exts.rst b/docs/users_guide/glasgow_exts.rst
index 4fc02f6d02..54f4c94bd6 100644
--- a/docs/users_guide/glasgow_exts.rst
+++ b/docs/users_guide/glasgow_exts.rst
@@ -5873,6 +5873,43 @@ to subsume the ``OverloadedStrings`` extension (currently, as a special
case, string literals benefit from statically allocated compact
representation).
+Recursive 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 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.
+
+However recursive superclasses are sometimes useful. Here's a real-life
+example (Trac #10318) ::
+
+ class (Frac (Frac a) ~ Frac a,
+ Fractional (Frac a),
+ IntegralDomain (Frac a))
+ => IntegralDomain a where
+ type Frac a :: *
+
+Here the superclass cycle does terminate but it's not entirely straightforward
+to see that it does.
+
+With the language extension ``-XRecursiveSuperClasses`` GHC will allow these
+class declarations. If there really *is* a loop, GHC will only
+expand it to finite depth.
+
+
.. _type-families:
Type families