6.8.2. Flexible contexts¶
-
FlexibleContexts
¶ Since: 6.8.1 Allow the use of complex constraints in class declaration contexts.
In Haskell 98 the context of a class declaration (which introduces
superclasses) must be simple; that is, each predicate must consist of a
class applied to type variables. The extension FlexibleContexts
(The context of a type signature) lifts this restriction, so that the only
restriction on the context in a class declaration is that the class
hierarchy must be acyclic. So these class declarations are OK:
class Functor (m k) => FiniteMap m k where
...
class (Monad m, Monad (t m)) => Transform t m where
lift :: m a -> (t m) a
As in Haskell 98, the class hierarchy must be acyclic. However, the definition of “acyclic” involves only the superclass relationships. For example, this is okay:
class C a where
op :: D b => a -> b -> b
class C a => D a where ...
Here, C
is a superclass of D
, but it’s OK for a class operation
op
of C
to mention D
. (It would not be OK for D
to be a
superclass of C
.)
With the extension that adds a kind of constraints, you can write more exotic superclass definitions. The superclass cycle check is even more liberal in these cases. For example, this is OK:
class A cls c where
meth :: cls c => c -> c
class A B c => B c where
A superclass context for a class C
is allowed if, after expanding
type synonyms to their right-hand-sides, and uses of classes (other than
C
) to their superclasses, C
does not occur syntactically in the
context.