6.6.7. Deriving strategies¶
-
DerivingStrategies
¶ 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 GeneralizedNewtypeDeriving
and
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 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
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
: UseDeriveAnyClass
(see Deriving any other class)newtype
: UseGeneralizedNewtypeDeriving
- (see Generalised derived instances for newtypes)
via
: UseDerivingVia
(see Deriving via)
6.6.7.1. Default deriving strategy¶
If an explicit deriving strategy is not given, multiple strategies may apply. In that case, GHC chooses the strategy as follows:
Stock type classes, i.e. those specified in the report and those enabled by language extensions, are derived using the
stock
strategy, with the following exception:- For newtypes,
Eq
,Ord
,Ix
andBounded
are always derived using thenewtype
strategy, even withoutGeneralizedNewtypeDeriving
enabled. (There should be no observable difference to instances derived using the stock strategy.) - Also for newtypes,
Functor
,Foldable
andEnum
are derived using thenewtype
strategy ifGeneralizedNewtypeDeriving
is enabled and the derivation succeeds.
- For newtypes,
For any other type class:
- When
DeriveAnyClass
is enabled, useanyclass
. - When
GeneralizedNewtypeDeriving
is enabled and we are deriving for a newtype, then usenewtype
.
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.- When