Note [Deriving strategies]
GHC has a notion of deriving strategies, which allow the user to explicitly request which approach to use when deriving an instance (enabled with the -XDerivingStrategies language extension). For more information, refer to the original issue (#10598) or the associated wiki page: https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/deriving-strategies 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 -XDerivingStrategies 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 -XDeriveAnyClass * newtype: Use -XGeneralizedNewtypeDeriving * via: Use -XDerivingVia The latter two strategies (newtype and via) are referred to as the "coerce-based" strategies, since they generate code that relies on the `coerce` function. See, for instance, GHC.Tc.Deriv.Infer.inferConstraintsCoerceBased. The former two strategies (stock and anyclass), in contrast, are referred to as the "originative" strategies, since they create "original" instances instead of "reusing" old instances (by way of `coerce`). See, for instance, GHC.Tc.Deriv.Utils.checkOriginativeSideConditions. If an explicit deriving strategy is not given, GHC has an algorithm it uses to determine which strategy it will actually use. The algorithm is quite long, so it lives in the Haskell wiki at https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/deriving-strategies ("The deriving strategy resolution algorithm" section). Internally, GHC uses the DerivStrategy datatype to denote a user-requested deriving strategy, and it uses the DerivSpecMechanism datatype to denote what GHC will use to derive the instance after taking the above steps. In other words, GHC will always settle on a DerivSpecMechnism, even if the user did not ask for a particular DerivStrategy (using the algorithm linked to above).
References 0
This Note does not link to any other.
Referenced by 12
- GHC.Tc.Deriv call site ×4
- GHC.Tc.Deriv.Utils call site ×4
- Language.Haskell.Syntax.Decls call site ×2
- Determining whether newtype-deriving is appropriate GHC.Tc.Deriv
- DerivEnv and DerivSpecMechanism GHC.Tc.Deriv.Utils