summaryrefslogtreecommitdiff
path: root/docs/users_guide/exts/deriving_strategies.rst
blob: 2a0e6b54b159bbb3d0f3993913490df13ee544c0 (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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
.. _deriving-strategies:

Deriving strategies
-------------------

.. extension:: DerivingStrategies
    :shortdesc: Enables deriving strategies.

    :since: 8.2.1

    Allow multiple ``deriving``, each optionally qualified with a *strategy*.

In most scenarios, every ``deriving`` statement generates a typeclass instance
in an unambiguous fashion. There is a corner case, however, where
simultaneously enabling both the :extension:`GeneralizedNewtypeDeriving` and
:extension:`DeriveAnyClass` extensions can make deriving become ambiguous.
Consider the following example ::

    {-# LANGUAGE DeriveAnyClass, GeneralizedNewtypeDeriving #-}
    newtype Foo = MkFoo Bar deriving C

One could either pick the ``DeriveAnyClass`` approach to deriving ``C`` or the
``GeneralizedNewtypeDeriving`` approach to deriving ``C``, both of which would
be equally as valid. GHC defaults to favoring ``DeriveAnyClass`` in such a
dispute, but this is not a satisfying solution, since that leaves users unable
to use both language extensions in a single module.

To make this more robust, GHC has a notion of deriving strategies, which allow
the user to explicitly request which approach to use when deriving an instance.
To enable this feature, one must enable the :extension:`DerivingStrategies`
language extension. A deriving strategy can be specified in a deriving
clause ::

    newtype Foo = MkFoo Bar
      deriving newtype C

Or in a standalone deriving declaration ::

    deriving anyclass instance C Foo

:extension:`DerivingStrategies` also allows the use of multiple deriving
clauses per data declaration so that a user can derive some instance with
one deriving strategy and other instances with another deriving strategy.
For example ::

    newtype Baz = Baz Quux
      deriving          (Eq, Ord)
      deriving stock    (Read, Show)
      deriving newtype  (Num, Floating)
      deriving anyclass C

Currently, the deriving strategies are:

- ``stock``: Have GHC implement a "standard" instance for a data type,
  if possible (e.g., ``Eq``, ``Ord``, ``Generic``, ``Data``, ``Functor``, etc.)

- ``anyclass``: Use :extension:`DeriveAnyClass` (see :ref:`derive-any-class`)

- ``newtype``: Use :extension:`GeneralizedNewtypeDeriving`
               (see :ref:`newtype-deriving`)

- ``via``: Use :extension:`DerivingVia` (see :ref:`deriving-via`)

.. _default-deriving-strategy:

Default deriving strategy
~~~~~~~~~~~~~~~~~~~~~~~~~

If an explicit deriving strategy is not given, multiple strategies may apply.
In that case, GHC chooses the strategy as follows:

1. Stock type classes, i.e. those specified in the report and those enabled by
   `language extensions <#deriving-extra>`__, are derived using the ``stock``
   strategy, with the following exception:

   * For newtypes, ``Eq``, ``Ord``, ``Ix`` and ``Bounded`` are always derived
     using the ``newtype`` strategy, even without
     ``GeneralizedNewtypeDeriving`` enabled. (There should be no observable
     difference to instances derived using the stock strategy.)

   * Also for newtypes, ``Functor``, ``Foldable`` and ``Enum`` are derived
     using the ``newtype`` strategy if ``GeneralizedNewtypeDeriving`` is
     enabled and the derivation succeeds.

2. For other any type class:

   1. When :extension:`DeriveAnyClass` is enabled, use ``anyclass``.

   2. When :extension:`GeneralizedNewtypeDeriving` is enabled and we are
      deriving for a newtype, then use ``newtype``.

   If both rules apply to a deriving clause, then ``anyclass`` is used and the
   user is warned about the ambiguity. The warning can be avoided by explicitly
   stating the desired deriving strategy.