| License | BSD-3-Clause |
|---|---|
| Maintainer | generics@haskell.org |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | Safe |
| Language | Haskell2010 |
Generics.Deriving.Default
Description
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.
Kind * (aka Type)
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 (DefaultMyType) deriving via (DefaultMyType) instanceGShowMyType
Instances may be parameterized by type variables.
data MyType1 a = … deriving (Generic) deriving (GShow) via (Default(MyType1 a)) deriving viaDefault(MyType1 a) instanceGEqa =>GEq(MyType1 a)
These types both require instances for Generic. This is because the
implementations of geq and gshowsPrec for have a Default b constraint, i.e. the type corresponding to Generic
bb require a Generic
instance. For these two types, that means instances for
and Generic MyType respectively.Generic (MyType1 a)
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.
This newtype wrapper can be used to derive default instances for
classes taking an argument of kind Type.
Instances
| (Generic a, GEq' (Rep a)) => GEq (Default a) Source # | |
| (Generic a, GEq a, Enum' (Rep a)) => GEnum (Default a) Source # | The |
Defined in Generics.Deriving.Default | |
| (Generic a, GSemigroup' (Rep a)) => GSemigroup (Default a) Source # | Semigroups often have many sensible implementations of
In other cases, one may wish to use the existing wrapper newtypes in
newtype FirstSemigroup = FirstSemigroup |
| (Generic a, GMonoid' (Rep a)) => GMonoid (Default a) Source # | |
| (Generic a, GShow' (Rep a)) => GShow (Default a) Source # | For example, with this type: newtype TestShow = TestShow
In this example, In general, when using a newtype wrapper, the instance can be derived
via the wrapped type, as here (via |
| (Generic a, Uniplate' (Rep a) a, Context' (Rep a) a) => Uniplate (Default a) Source # | |
Defined in Generics.Deriving.Default Methods children :: Default a -> [Default a] Source # context :: Default a -> [Default a] -> Default a Source # descend :: (Default a -> Default a) -> Default a -> Default a Source # descendM :: Monad m => (Default a -> m (Default a)) -> Default a -> m (Default a) Source # transform :: (Default a -> Default a) -> Default a -> Default a Source # transformM :: Monad m => (Default a -> m (Default a)) -> Default a -> m (Default a) Source # | |
Kind * -> * (aka Type -> Type)
For classes which take an argument of kind , use Type ->
TypeDefault1. 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 (Default1MyType1) deriving via (Default1MyType1) instanceGFoldableMyType1
Note that these instances require a constraint as
Generic1 MyType1gmap and gfoldMap have constraints on the
implementations for Generic1 a.Default1 a
This newtype wrapper can be used to derive default instances for
classes taking an argument of kind .Type -> Type
Constructors
| Default1 | |
Fields
| |
Instances
Other kinds
These principles extend to classes taking arguments of other kinds.