6.8.2. Flexible contexts — Glasgow Haskell Compiler 9.0.2 User's Guide

# 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.