summaryrefslogtreecommitdiff
path: root/docs/users_guide/exts/constrained_class_methods.rst
blob: c1630fbd5402e61995a038c001f3875fe231a590 (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
.. _class-method-types:

Constrained class method types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. extension:: ConstrainedClassMethods
    :shortdesc: Enable constrained class methods.

    :since: 6.8.1

    :status: Included in :extension:`GHC2021`

    Allows the definition of further constraints on individual class methods.

Haskell 98 prohibits class method types to mention constraints on the
class type variable, thus: ::

      class Seq s a where
        fromList :: [a] -> s a
        elem     :: Eq a => a -> s a -> Bool

The type of ``elem`` is illegal in Haskell 98, because it contains the
constraint ``Eq a``, which constrains only the class type variable (in
this case ``a``). More precisely, a constraint in a class method signature is rejected if

- The constraint mentions at least one type variable.  So this is allowed: ::

     class C a where
       op1 :: HasCallStack => a -> a
       op2 :: (?x::Int) => Int -> a

- All of the type variables mentioned are bound by the class declaration, and none is locally quantified.  Examples: ::

     class C a where
       op3 :: Eq a => a -> a    -- Rejected: constrains class variable only
       op4 :: D b => a -> b     -- Accepted: constrains a locally-quantified variable `b`
       op5 :: D (a,b) => a -> b -- Accepted: constrains a locally-quantified variable `b`


GHC lifts this restriction with language extension
:extension:`ConstrainedClassMethods`. The restriction is a pretty stupid one in
the first place, so :extension:`ConstrainedClassMethods` is implied by
:extension:`MultiParamTypeClasses`.