generic-deriving: Generic programming library for generalised deriving

Hackage Hackage Dependencies Haskell Programming Language BSD3 License Build Status

This package provides functionality for generalising the deriving mechanism in Haskell to arbitrary classes. It was first described in the paper:

The current implementation integrates with the new GHC Generics. See http://www.haskell.org/haskellwiki/GHC.Generics for more information. Template Haskell code is provided for supporting older GHCs.

This library is organized as follows:

  • Generics.Deriving.Base defines the core functionality for GHC generics, including the Generic(1) classes and representation data types. On modern versions of GHC, this simply re-exports GHC.Generics from base. On older versions of GHC, this module backports parts of GHC.Generics that were not included at the time, including Generic(1) instances.

  • Generics.Deriving.TH implements Template Haskell functionality for deriving instances of Generic(1).

  • Educational code: in order to provide examples of how to define and use GHC.Generics-based defaults, this library offers a number of modules which define examples of type classes along with default implementations for the classes’ methods. Currently, the following modules are provided:

    • Generics.Deriving.Copoint

    • Generics.Deriving.ConNames

    • Generics.Deriving.Enum

    • Generics.Deriving.Eq

    • Generics.Deriving.Foldable

    • Generics.Deriving.Functor

    • Generics.Deriving.Monoid

    • Generics.Deriving.Semigroup

    • Generics.Deriving.Show

    • Generics.Deriving.Traversable

    • Generics.Deriving.Uniplate

    It is worth emphasizing that these modules are primarly intended for educational purposes. Many of the classes in these modules resemble other commonly used classes—for example, GShow from Generics.Deriving.Show resembles Show from base—but in general, the classes that generic-deriving defines are not drop-in replacements. Moreover, the generic defaults that generic-deriving provide often make simplifying assumptions that may violate expectations of how these classes might work elsewhere. For example, the generic default for GShow does not behave exactly like deriving Show would.

    If you are seeking GHC.Generics-based defaults for type classes in base, consider using the generic-data library.

  • Generics.Deriving.Default provides newtypes that allow leveraging the generic defaults in this library using the DerivingVia GHC language extension.

  • Generics.Deriving re-exports Generics.Deriving.Base, Generics.Deriving.Default, and a selection of educational modules.

Changes

1.14.5 [2023.08.06]

  • Support building with template-haskell-2.21.* (GHC 9.8).
  • The Template Haskell machinery now uses TemplateHaskellQuotes when building with GHC 8.0+ instead of manually constructing each Template Haskell Name. A consequence of this is that generic-deriving will now build with GHC 9.8, as TemplateHaskellQuotes abstracts over some internal Template Haskell changes introduced in 9.8.

1.14.4 [2023.04.30]

  • Allow building with GHC backends where HTYPE_SIG_ATOMIC_T is not defined, such as the WASM backend.
  • Place INLINE [1] pragmas on from and to implementations when types don’t have too many constructors or fields, following the heuristics that GHC 9.2+ uses for Generic deriving.

1.14.3 [2023.02.27]

  • Support th-abstraction-0.5.*.

1.14.2 [2022.07.23]

  • Fix a bug in which deriveAll1 could generate ill kinded code when using kindSigOptions=False, or when using GHC 8.0 or earlier.
  • Fix a bug in which deriveAll1 would reject data types whose last type variable has a kind besides Type or k on GHC 8.2 or later.

1.14.1 [2021.08.30]

  • Backport the Generic(1) instances introduced for tuples (8 through 15) in base-4.16.
  • Make the test suite compile on GHC 9.2 or later.
  • Always import Data.List qualified to fix the build with recent GHCs.

1.14 [2020.09.30]

  • Remove instances for Data.Semigroup.Option, which is deprecated as of base-4.15.0.0.
  • Allow building with template-haskell-2.17.0.0 (GHC 9.0).
  • Fix a bug in which deriveAll1 would needlessly reject data types whose last type parameter appears as an oversaturated argument to a type family.

1.13.1 [2019.11.26]

  • Backport the Generic(1) instances for Kleisli introduced in base-4.14.

1.13 [2019.08.27]

  • Make GSemigroup a superclass of GMonoid. Similarly, make GSemigroup' a superclass of GMonoid'.
  • In the instance GMonoid (Maybe a), relax the constraint on a from GMonoid to GSemigroup.

1.12.4 [2019.04.26]

  • Support th-abstraction-0.3.0.0 or later.

1.12.3 [2019.02.09]

  • Support template-haskell-2.15.
  • Add a gshowList method to GShow, which lets us avoid the need for OverlappingInstances in Generics.Deriving.TH. As a consequence, the GShow String instance has been removed, as it is now fully subsumed by the GShow [a] instance (with which it previously overlapped).
  • Functions in Generics.Deriving.TH now balance groups of (:*:) and (:+:) as much as possible (deriving Generic was already performing this optimization, and now generic-deriving does too).
  • Add a Generics.Deriving.Default module demonstrating and explaining how and why to use DerivingVia. There is also a test suite with further examples.

1.12.2 [2018.06.28]

  • Backport the Generic(1) instances for Data.Ord.Down, introduced in base-4.12. Add GEq, GShow, GSemigroup, GMonoid, GFunctor, GFoldable, GTraversable, and GCopoint instances for Down.
  • Refactor internals using th-abstraction.
  • Adapt to Maybe moving to GHC.Maybe in GHC 8.6.

1.12.1 [2018.01.11]

  • Remove a test that won’t work on GHC 8.4.

1.12 [2017.12.07]

  • Adapt to the EmptyDataDeriving proposal (introduced in GHC 8.4):
    • Generics.Deriving.TH now derives to(1) and from(1) implementations for empty data types that are strict in the argument.
    • Introduce an EmptyCaseOptions field to Options in Generics.Deriving.TH, which controls whether generated from(1)/to(1) implementations for empty data types should use the EmptyCase extension or not (as is the case in GHC 8.4).
    • Add mkFrom0Options, mkFrom1Options, mkTo0Options, and mkTo1Options functions to Generics.Deriving.TH, which take EmptyCaseOptions as arguments.
    • The backported instances for V1 are now maximally lazy, as per EmptyDataDeriving. (Previously, some instances would unnecessarily force their argument, such as the Eq and Ord instances.)
    • Add instances for V1 in Generics.Deriving.Copoint, .Eq, .Foldable, .Functor, .Show, and .Traversable.
  • Remove the bitrotting simplInstance function from Generics.Deriving.TH.

1.11.2 [2017.04.10]

  • Add GEq, GShow, GEnum, and GIx instances for the new data types in Foreign.C.Types (CBool) and System.Posix.Types (CBlkSize, CBlkCnt, CClockId, CFsBlkCnt, CFsFilCnt, CId, CKey, and CTimer) introduced in base-4.10.0.0

1.11.1 [2016.09.10]

  • Fix Template Haskell regression involving data families
  • Convert examples to test suite
  • Backport missing Data and Typeable instances for Rec1, M1, (:*:), (:+:), and (:.:)

1.11

  • The behavior of functions in Generics.Deriving.TH have changed with respect to when type synonyms are generated for Rep(1) definitions. In particular:

    • By default, deriveRepresentable(1) will no longer define its Rep(1) type family instance in terms of the type synonym that has to be generated with deriveRep(1). Similarly, deriveAll(1) and deriveAll0And1 will no longer generate a type synonym. Instead, they will generate Generic(1) instances that directly define the Rep(1) instance inline. If you wish to revert to the old behavior, you will need to use the variants of those functions suffixed with -Options.
    • New functions makeRep0Inline and makeRep1Inline have been added which, for most purposes, should replace uses of makeRep0/makeRep0FromType and makeRep1/makeRep1FromType (but see the next bullet point for a caveat).
    • The use of deriveRep(1), makeRep0/makeRep0FromType, and makeRep1/makeRep1FromType are now discouraged, but those functions are still available. The reason is that on GHC 7.0/7.2/7.4, it is impossible to use makeRep0Inline/makeRep1Inline due to a GHC bug. Therefore, you must use makeRep0/makeRep1 and deriveRep(1) on GHC 7.0/7.2/7.4 out of necessity.

    These changes make dealing with Generic instances that involve PolyKinds and TypeInType much easier.

  • All functions suffixed in -WithKindSigs in Generics.Deriving.TH have been removed in favor of a more sensible -Options suffixing scheme. The ability to toggle whether explicit kind signatures are used on type variable binders has been folded into KindSigOptions, which is an explicit argument to deriveRep0Options/deriveRep1Options and also a field in the more general ‘Options’ data type.

  • Furthermore, the behavior of derived instances’ kind signatures has changed. By default, the TH code will now always use explicit kind signatures whenever possible, regardless of whether you’re working with plain data types or data family instances. This makes working with TypeInType less surprising, but at the cost of making it slightly more awkward to work with derived Generic1 instances that constrain kinds to * by means of (:.:).

  • Since Generic1 is polykinded on GHC 8.2 and later, the functions in Generics.Deriving.TH will no longer unify the kind of the last type parameter to be *.

  • Fix a bug in which makeRep (and similarly named functions) would not check whether the argument type can actually have a well kinded Generic(1) instance.

  • Backport missing Foldable and Traversable instances for Rec1

1.10.7

1.10.6

  • A new base-4-9 Cabal flag was added to more easily facilitate installing generic-deriving with manually installed versions of template-haskell.

1.10.5

1.10.4.1

  • Fix Haddock parsing issue on GHC 8.0

1.10.4

  • Backported MonadPlus and MonadZip instances for U1, and made the Functor, Foldable, Traversable, Alternative, and Monad instances for U1 lazier to correspond with base-4.9

1.10.3

  • Backported Enum, Bounded, Ix, Functor, Applicative, Monad, MonadFix, MonadPlus, MonadZip, Foldable, Traversable, and Data instances (introduced in base-4.9) for datatypes in the Generics.Deriving.Base module

1.10.2

  • Fix TH regression on GHC 7.0

1.10.1

  • Added Generics.Deriving.Semigroup
  • Added GMonoid instance for Data.Monoid.Alt
  • Fixed a bug in the GEnum instances for unsigned Integral types
  • Added Safe/Trustworthy pragmas
  • Made instances polykinded where possible

1.10.0

  • On GHC 8.0 and up, Generics.Deriving.TH uses the new type literal-based machinery
  • Rewrote the Template Haskell code to be robust. Among other things, this fixes a bug with deriving Generic1 instances on GHC 7.8, and makes it easier to derive Generic1 instances for datatypes that utilize GHC 8.0’s -XTypeInType extension.
  • Added deriveAll0 and makeRep0 for symmetry with deriveAll1 and makeRep1
  • AddedmakeRep0FromType and makeRep1FromType to make it easier to pass in the type instance (instead of having to pass each individual type variable, which can be error-prone)
  • Added functions with the suffix -WithKindSigs to allow generating type synonyms with explicit kind signatures in the presence of kind-polymorphic type variables. This is necessary for some datatypes that use -XTypeInType to have derived Generic(1) instances, but is not turned on by default since the TH kind inference is not perfect and would cause otherwise valid code to be rejected. Use only if you know what you are doing.
  • Fixed bug where a datatype with a single, nullary constructor would generate incorrect Generic instances
  • More sensible GEnum instances for fixed-size integral types
  • Added GCopoint, GEnum, GEq, GFoldable, GFunctor, GMonoid, GShow, and GTraversable instances for datatypes introduced in GHC 8.0
  • Backported Generic(1) instances added in GHC 8.0. Specifically, Generic instances for Complex (base-4.4 and later) ExitCode, and Version; and Generic1 instances for Complex (base-4.4 and later) and Proxy (base-4.7 and later). Added GEnum, GEq, GFoldable, GFunctor, GIx, GShow, and GTraversable instances for these datatypes where appropriate.

1.9.0

  • Allow deriving of Generic1 using Template Haskell
  • Allow deriving of Generic(1) for data families
  • Allow deriving of Generic(1) for constructor-less plain datatypes (but not data families, due to technical restrictions)
  • Support for unboxed representation types on GHC 7.11+
  • More GCopoint, GEnum, GEq, GFoldable, GFunctor, GIx, GMonoid, GShow, and GTraversable instances
  • The field accessors for the (:+:) type in Generics.Deriving.Base have been removed to be consistent with GHC.Generics
  • Ensure that TH generates definitions for isNewtype and packageName, if a recent-enough version of GHC is used
  • Ensure that TH-generated names are unique for a given data type’s module and package (similar in spirit to Trac #10487)
  • Allow building on stage-1 compilers