HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Modulegeneric-deriving-1.14.6Haskell2010

Generics.Deriving.Default

GHC 8.6 introduced the DerivingVia language extension, which means a typeclass instance can be derived from an existing instance for an isomorphic type. Any newtype is isomorphic to the underlying type. By implementing a typeclass once for the newtype, it is possible to derive any typeclass for any type with a Generic instance.

For a number of classes, there are sensible default instantiations. In older GHCs, these can be supplied in the class definition, using the DefaultSignatures extension. However, only one default can be provided! With DerivingVia it is now possible to choose from many default instantiations.

This package contains a number of such classes. This module demonstrates how one might create a family of newtypes (Default, Default1) for which such instances are defined.

One might then use DerivingVia as follows. The implementations of the data types are elided here (they are irrelevant). For most cases, either the deriving clause with the data type definition or the standalone clause will work (for some types it is necessary to supply the context explicitly using the latter form). See the source of this module for the implementations of instances for the Default family of newtypes and the source of the test suite for some types which derive instances via these wrappers.

  • 2 types

Kind * (aka Type)

1 declaration

For classes which take an argument of kind Type, use Default. An example of this class from base would be Eq, or Generic.

These examples use GShow and GEq; they are interchangeable.

data MyType = …
 deriving (Generic)
 deriving (GEq) via (Default MyType)

deriving via (Default MyType) instance GShow MyType

Instances may be parameterized by type variables.

data MyType1 a = …
 deriving (Generic)
 deriving (GShow) via (Default (MyType1 a))

deriving via Default (MyType1 a) instance GEq a => GEq (MyType1 a)

These types both require instances for Generic. This is because the implementations of geq and gshowsPrec for Default b have a Generic b constraint, i.e. the type corresponding to b require a Generic instance. For these two types, that means instances for Generic MyType and Generic (MyType1 a) respectively.

It also means the Generic instance is not needed when there is already a generic instance for the type used to derive the relevant instances. For an example, see the documentation of the GShow instance for Default, below.

newtypenewtype Default a
#

This newtype wrapper can be used to derive default instances for classes taking an argument of kind Type.

Constructors

Instances6GEnum, GEq, GShow, Uniplate, GMonoid, GSemigroup

Kind * -> * (aka Type -> Type)

1 declaration

For classes which take an argument of kind Type -> Type, use Default1. An example of this class from base would be Eq1, or Generic1.

Unlike for MyType1, there can be no implementation of these classes for MyType :: Type.

data MyType1 a = …
 deriving (Generic1)
 deriving (GFunctor) via (Default1 MyType1)

deriving via (Default1 MyType1) instance GFoldable MyType1

Note that these instances require a Generic1 MyType1 constraint as gmap and gfoldMap have Generic1 a constraints on the implementations for Default1 a.

newtypenewtype Default1 (f :: Type -> Type) a
#

This newtype wrapper can be used to derive default instances for classes taking an argument of kind Type -> Type.

Constructors

Instances4GCopoint, GFunctor, GFoldable, GTraversable

Other kinds

0 declarations

These principles extend to classes taking arguments of other kinds.