deriving-compat-0.5.9: Backports of GHC deriving extensions

Copyright | (C) 2015-2017 Ryan Scott
License | BSD-style (see the file LICENSE)
Maintainer | Ryan Scott
Portability | Template Haskell
Safe Haskell | None
Language | Haskell2010

Data.Deriving.Via.Internal

Description

On `template-haskell-2.12` or later (i.e., GHC 8.2 or later), this module exports functionality which emulates the `GeneralizedNewtypeDeriving` and `DerivingVia` GHC extensions (the latter of which was introduced in GHC 8.6).

On older versions of `template-haskell`/GHC, this module does not export anything.

Note: this is an internal module, and as such, the API presented here is not guaranteed to be stable, even between minor releases of this library.

Synopsis

- deriveGND :: Q Type -> Q [Dec]
- deriveVia :: Q Type -> Q [Dec]
- deriveViaDecs :: Type -> Maybe Type -> Q [Dec]
- deriveViaDecs' :: Name -> [TyVarBndr] -> [Type] -> Type -> Dec -> Q (Maybe [Dec])
- mkCoerceClassMethEqn :: [TyVarBndr] -> [Type] -> Type -> Type -> (Type, Type)
- zipTvbSubst :: [TyVarBndr] -> [Type] -> Map Name Type
- changeLast :: [a] -> a -> [a]
- stripOuterForallT :: Type -> Type
- decomposeType :: Type -> ([TyVarBndr], Cxt, Type)
- newtypeRepType :: DatatypeVariant -> [ConstructorInfo] -> Maybe Type
- etaReduce :: Int -> Type -> Maybe Type

# Documentation

deriveGND :: Q Type -> Q [Dec] Source #

Generates an instance for a type class at a newtype by emulating the behavior of the `GeneralizedNewtypeDeriving` extension. For example:

    newtype Foo a = MkFoo a
    $(deriveGND [t| forall a. Eq a => Eq (Foo a) |])

deriveVia :: Q Type -> Q [Dec] Source #

Generates an instance for a type class by emulating the behavior of the `DerivingVia` extension. For example:

    newtype Foo a = MkFoo a
    $(deriveVia [t| forall a. Ord a => Ord (Foo a) `Via` Down a |])

As shown in the example above, the syntax is a tad strange. One must specify the type by which to derive the instance using the `Via` type. This requirement is in place to ensure that the type variables are scoped correctly across all the types being used (e.g., to make sure that the same `a` is used in ``Ord` a`, ``Ord` (Foo a)`, and `Down a`).

deriveViaDecs Source #

Arguments

:: Type | The instance head (e.g., `Eq (Foo a)`)
-> Maybe Type | If using `deriveGND`, this is 'Nothing. If using `deriveVia`, this is `Just` the `via` type.
-> Q [Dec] |

deriveViaDecs' :: Name -> [TyVarBndr] -> [Type] -> Type -> Dec -> Q (Maybe [Dec]) Source #

mkCoerceClassMethEqn :: [TyVarBndr] -> [Type] -> Type -> Type -> (Type, Type) Source #

zipTvbSubst :: [TyVarBndr] -> [Type] -> Map Name Type Source #

changeLast :: [a] -> a -> [a] Source #

Replace the last element of a list with another element.

stripOuterForallT :: Type -> Type Source #

decomposeType :: Type -> ([TyVarBndr], Cxt, Type) Source #

newtypeRepType :: DatatypeVariant -> [ConstructorInfo] -> Maybe Type Source #

etaReduce :: Int -> Type -> Maybe Type Source #