th-abstraction-0.7.1.0: Nicer interface for reified information about data types

Copyright | Eric Mertens 2017-2020
License | ISC
Maintainer | emertens@gmail.com
Safe Haskell | Safe
Language | Haskell2010

Language.Haskell.TH.Datatype

Contents

- Types
- Normalization functions
- `DatatypeInfo` lookup functions
- Type variable manipulation
- `Pred` functions
- Backward compatible data definitions
- Strictness annotations
- Type simplification
- Fixities
- Convenience functions

Description

This module provides a flattened view of information about data types and newtypes that can be supported uniformly across multiple versions of the `template-haskell` package.

Sample output for ``reifyDatatype` ''Maybe`

    DatatypeInfo
     { datatypeContext   = []
     , datatypeName      = GHC.Base.Maybe
     , datatypeVars      = [ KindedTV a_3530822107858468866 () StarT ]
     , datatypeInstTypes = [ SigT (VarT a_3530822107858468866) StarT ]
     , datatypeVariant   = Datatype
     , datatypeReturnKind = StarT
     , datatypeCons      =
         [ ConstructorInfo
             { constructorName       = GHC.Base.Nothing
             , constructorVars       = []
             , constructorContext    = []
             , constructorFields     = []
             , constructorStrictness = []
             , constructorVariant    = NormalConstructor
             }
         , ConstructorInfo
             { constructorName       = GHC.Base.Just
             , constructorVars       = []
             , constructorContext    = []
             , constructorFields     = [ VarT a_3530822107858468866 ]
             , constructorStrictness = [ FieldStrictness
                                             UnspecifiedUnpackedness
                                             Lazy
                                         ]
             , constructorVariant    = NormalConstructor
             }
         ]
     }

Datatypes declared with GADT syntax are normalized to constructors with existentially quantified type variables and equality constraints.

Synopsis

- data DatatypeInfo = DatatypeInfo {
  - datatypeContext :: Cxt
  - datatypeName :: Name
  - datatypeVars :: [TyVarBndrUnit]
  - datatypeInstTypes :: [Type]
  - datatypeVariant :: DatatypeVariant
  - datatypeReturnKind :: Kind
  - datatypeCons :: [ConstructorInfo]
  }
- data ConstructorInfo = ConstructorInfo {
  - constructorName :: Name
  - constructorVars :: [TyVarBndrUnit]
  - constructorContext :: Cxt
  - constructorFields :: [Type]
  - constructorStrictness :: [FieldStrictness]
  - constructorVariant :: ConstructorVariant
  }
- data DatatypeVariant
  - = Datatype
  - | Newtype
  - | DataInstance
  - | NewtypeInstance
  - | TypeData
- data ConstructorVariant
  - = NormalConstructor
  - | InfixConstructor
  - | RecordConstructor [Name]
- data FieldStrictness = FieldStrictness {
  - fieldUnpackedness :: Unpackedness
  - fieldStrictness :: Strictness
  }
- data Unpackedness
  - = UnspecifiedUnpackedness
  - | NoUnpack
  - | Unpack
- data Strictness
  - = UnspecifiedStrictness
  - | Lazy
  - | Strict
- reifyDatatype :: Name -> Q DatatypeInfo
- reifyConstructor :: Name -> Q ConstructorInfo
- reifyRecord :: Name -> Q ConstructorInfo
- normalizeInfo :: Info -> Q DatatypeInfo
- normalizeDec :: Dec -> Q DatatypeInfo
- normalizeCon :: Name -> [TyVarBndrUnit] -> [Type] -> Kind -> DatatypeVariant -> Con -> Q [ConstructorInfo]
- lookupByConstructorName :: Name -> DatatypeInfo -> ConstructorInfo
- lookupByRecordName :: Name -> DatatypeInfo -> ConstructorInfo
- class TypeSubstitution a where
  - applySubstitution :: Map Name Type -> a -> a
  - freeVariables :: a -> [Name]
- quantifyType :: Type -> Type
- freeVariablesWellScoped :: [Type] -> [TyVarBndrUnit]
- freshenFreeVariables :: Type -> Q Type
- equalPred :: Type -> Type -> Pred
- classPred :: Name -> [Type] -> Pred
- asEqualPred :: Pred -> Maybe (Type, Type)
- asClassPred :: Pred -> Maybe (Name, [Type])
- dataDCompat :: CxtQ -> Name -> [TyVarBndrVis] -> [ConQ] -> [Name] -> DecQ
- newtypeDCompat :: CxtQ -> Name -> [TyVarBndrVis] -> ConQ -> [Name] -> DecQ
- tySynInstDCompat :: Name -> Maybe [Q TyVarBndrUnit] -> [TypeQ] -> TypeQ -> DecQ
- pragLineDCompat :: Int -> String -> Maybe DecQ
- arrowKCompat :: Kind -> Kind -> Kind
- isStrictAnnot :: FieldStrictness
- notStrictAnnot :: FieldStrictness
- unpackedAnnot :: FieldStrictness
- resolveTypeSynonyms :: Type -> Q Type
- resolveKindSynonyms :: Kind -> Q Kind
- resolvePredSynonyms :: Pred -> Q Pred
- resolveInfixT :: Type -> Q Type
- reifyFixityCompat :: Name -> Q (Maybe Fixity)
- showFixity :: Fixity -> String
- showFixityDirection :: FixityDirection -> String
- unifyTypes :: [Type] -> Q (Map Name Type)
- tvName :: TyVarBndr_ flag -> Name
- tvKind :: TyVarBndr_ flag -> Kind
- datatypeType :: DatatypeInfo -> Type

# Types

data DatatypeInfo Source #

Normalized information about newtypes and data types.

`DatatypeInfo` contains two fields, `datatypeVars` and `datatypeInstTypes`, which encode information about the argument types. The simplest explanation is that `datatypeVars` contains all the type variables bound by the data type constructor, while `datatypeInstTypes` contains the type arguments to the data type constructor. To be more precise:

- For ADTs declared with `data` and `newtype`, it will likely be the case that `datatypeVars` and `datatypeInstTypes` coincide. For instance, given `newtype Id a = MkId a`, in the `DatatypeInfo` for `Id` we would have ``datatypeVars` = [`KindedTV` a () `StarT`]` and ``datatypeInstVars` = [`SigT` (`VarT` a) `StarT`]`.

ADTs that leverage `PolyKinds` may have more `datatypeVars` than `datatypeInstTypes`. For instance, given `data Proxy (a :: k) = MkProxy`, in the `DatatypeInfo` for `Proxy` we would have ``datatypeVars` = [`KindedTV` k () `StarT`, `KindedTV` a () (`VarT` k)]` (since there are two variables, `k` and `a`), whereas ``datatypeInstTypes` = [`SigT` (`VarT` a) (`VarT` k)]`, since there is only one explicit type argument to `Proxy`.

The same outcome would occur if `Proxy` were declared using `TypeAbstractions`, i.e., if it were declared as `data Proxy @k (a :: k) = MkProxy`. The `datatypeInstTypes` would not include a separate type for `@k`.

- For `data instance`s and `newtype instance`s of data families, `datatypeVars` and `datatypeInstTypes` can be quite different. Here is an example to illustrate the difference:

      data family F a b
      data instance F (Maybe c) (f x) = MkF c (f x)

Then in the `DatatypeInfo` for `F`'s data instance, we would have:

      datatypeVars      = [ KindedTV c () StarT
                            , KindedTV f () StarT
                            , KindedTV x () StarT ]
      datatypeInstTypes = [ AppT (ConT ''Maybe) (VarT c)
                            , AppT (VarT f) (VarT x) ]

Constructors

DatatypeInfo |

Fields

- datatypeContext :: Cxt

  Data type context (deprecated)

- datatypeName :: Name

  Type constructor

- datatypeVars :: [TyVarBndrUnit]

  Type parameters

- datatypeInstTypes :: [Type]

  Argument types

- datatypeVariant :: DatatypeVariant

  Extra information

- datatypeReturnKind :: Kind

  Return `Kind` of the type.

  If normalization is unable to determine the return kind, then this is conservatively set to `StarT`.

- datatypeCons :: [ConstructorInfo]

  Normalize constructor information

#### Instances

Instances details

Data DatatypeInfo Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> DatatypeInfo -> c DatatypeInfo Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c DatatypeInfo Source #

toConstr :: DatatypeInfo -> Constr Source #

dataTypeOf :: DatatypeInfo -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c DatatypeInfo) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DatatypeInfo) Source #

gmapT :: (forall b. Data b => b -> b) -> DatatypeInfo -> DatatypeInfo Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> DatatypeInfo -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> DatatypeInfo -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo Source #

Generic DatatypeInfo Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Associated Types

type Rep DatatypeInfo |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep DatatypeInfo = D1 ('MetaData "DatatypeInfo" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "DatatypeInfo" 'PrefixI 'True) ((S1 ('MetaSel ('Just "datatypeContext") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Cxt) :*: (S1 ('MetaSel ('Just "datatypeName") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Name) :*: S1 ('MetaSel ('Just "datatypeVars") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [TyVarBndrUnit]))) :*: ((S1 ('MetaSel ('Just "datatypeInstTypes") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Type]) :*: S1 ('MetaSel ('Just "datatypeVariant") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 DatatypeVariant)) :*: (S1 ('MetaSel ('Just "datatypeReturnKind") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Kind) :*: S1 ('MetaSel ('Just "datatypeCons") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [ConstructorInfo])))))

Methods

from :: DatatypeInfo -> Rep DatatypeInfo x Source #

to :: Rep DatatypeInfo x -> DatatypeInfo Source #

Show DatatypeInfo Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods showsPrec :: Int -> DatatypeInfo -> ShowS Source # show :: DatatypeInfo -> String Source # showList :: [DatatypeInfo] -> ShowS Source #
Eq DatatypeInfo Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods (==) :: DatatypeInfo -> DatatypeInfo -> Bool Source # (/=) :: DatatypeInfo -> DatatypeInfo -> Bool Source #
type Rep DatatypeInfo Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep DatatypeInfo = D1 ('MetaData "DatatypeInfo" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "DatatypeInfo" 'PrefixI 'True) ((S1 ('MetaSel ('Just "datatypeContext") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Cxt) :*: (S1 ('MetaSel ('Just "datatypeName") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Name) :*: S1 ('MetaSel ('Just "datatypeVars") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [TyVarBndrUnit]))) :*: ((S1 ('MetaSel ('Just "datatypeInstTypes") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Type]) :*: S1 ('MetaSel ('Just "datatypeVariant") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 DatatypeVariant)) :*: (S1 ('MetaSel ('Just "datatypeReturnKind") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Kind) :*: S1 ('MetaSel ('Just "datatypeCons") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [ConstructorInfo])))))

data ConstructorInfo Source #

Normalized information about constructors associated with newtypes and data types.

Constructors

ConstructorInfo |

Fields

- constructorName :: Name

  Constructor name

- constructorVars :: [TyVarBndrUnit]

  Constructor type parameters

- constructorContext :: Cxt

  Constructor constraints

- constructorFields :: [Type]

  Constructor fields

- constructorStrictness :: [FieldStrictness]

  Constructor fields' strictness (Invariant: has the same length as constructorFields)

- constructorVariant :: ConstructorVariant

  Extra information

#### Instances

Instances details

Data ConstructorInfo Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> ConstructorInfo -> c ConstructorInfo Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c ConstructorInfo Source #

toConstr :: ConstructorInfo -> Constr Source #

dataTypeOf :: ConstructorInfo -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c ConstructorInfo) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ConstructorInfo) Source #

gmapT :: (forall b. Data b => b -> b) -> ConstructorInfo -> ConstructorInfo Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> ConstructorInfo -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> ConstructorInfo -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> ConstructorInfo -> m ConstructorInfo Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> ConstructorInfo -> m ConstructorInfo Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> ConstructorInfo -> m ConstructorInfo Source #

Generic ConstructorInfo Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Associated Types

type Rep ConstructorInfo |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep ConstructorInfo = D1 ('MetaData "ConstructorInfo" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "ConstructorInfo" 'PrefixI 'True) ((S1 ('MetaSel ('Just "constructorName") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Name) :*: (S1 ('MetaSel ('Just "constructorVars") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [TyVarBndrUnit]) :*: S1 ('MetaSel ('Just "constructorContext") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Cxt))) :*: (S1 ('MetaSel ('Just "constructorFields") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Type]) :*: (S1 ('MetaSel ('Just "constructorStrictness") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [FieldStrictness]) :*: S1 ('MetaSel ('Just "constructorVariant") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 ConstructorVariant)))))

Methods

from :: ConstructorInfo -> Rep ConstructorInfo x Source #

to :: Rep ConstructorInfo x -> ConstructorInfo Source #

Show ConstructorInfo Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods showsPrec :: Int -> ConstructorInfo -> ShowS Source # show :: ConstructorInfo -> String Source # showList :: [ConstructorInfo] -> ShowS Source #
Eq ConstructorInfo Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods (==) :: ConstructorInfo -> ConstructorInfo -> Bool Source # (/=) :: ConstructorInfo -> ConstructorInfo -> Bool Source #
TypeSubstitution ConstructorInfo Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods applySubstitution :: Map Name Type -> ConstructorInfo -> ConstructorInfo Source # freeVariables :: ConstructorInfo -> [Name] Source #
type Rep ConstructorInfo Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep ConstructorInfo = D1 ('MetaData "ConstructorInfo" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "ConstructorInfo" 'PrefixI 'True) ((S1 ('MetaSel ('Just "constructorName") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Name) :*: (S1 ('MetaSel ('Just "constructorVars") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [TyVarBndrUnit]) :*: S1 ('MetaSel ('Just "constructorContext") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Cxt))) :*: (S1 ('MetaSel ('Just "constructorFields") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Type]) :*: (S1 ('MetaSel ('Just "constructorStrictness") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [FieldStrictness]) :*: S1 ('MetaSel ('Just "constructorVariant") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 ConstructorVariant)))))

data DatatypeVariant Source #

Possible variants of data type declarations.

Constructors

Datatype | Type declared with `data` or a primitive datatype.
Newtype | Type declared with `newtype`. A `DatatypeInfo` that uses `Newtype` will uphold the invariant that there will be exactly one `ConstructorInfo` in the `datatypeCons`.
DataInstance | Type declared with `data instance`.
NewtypeInstance | Type declared with `newtype instance`. A `DatatypeInfo` that uses `NewtypeInstance` will uphold the invariant that there will be exactly one `ConstructorInfo` in the `datatypeCons`.

TypeData

Type declared with `type data`.

A `DatatypeInfo` that uses `TypeData` will uphold the following invariants:

- The `datatypeContext` will be empty.
- None of the `constructorVariant`s in any of the `datatypeCons` will be `RecordConstructor`.
- Each of the `constructorStrictness` values in each of the `datatypeCons` will be equal to `notStrictAnnot`.

#### Instances

Instances details

Data DatatypeVariant Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> DatatypeVariant -> c DatatypeVariant Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c DatatypeVariant Source #

toConstr :: DatatypeVariant -> Constr Source #

dataTypeOf :: DatatypeVariant -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c DatatypeVariant) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DatatypeVariant) Source #

gmapT :: (forall b. Data b => b -> b) -> DatatypeVariant -> DatatypeVariant Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> DatatypeVariant -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> DatatypeVariant -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> DatatypeVariant -> m DatatypeVariant Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> DatatypeVariant -> m DatatypeVariant Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> DatatypeVariant -> m DatatypeVariant Source #

Generic DatatypeVariant Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Associated Types

type Rep DatatypeVariant |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep DatatypeVariant = D1 ('MetaData "DatatypeVariant" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) ((C1 ('MetaCons "Datatype" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Newtype" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "DataInstance" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "NewtypeInstance" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "TypeData" 'PrefixI 'False) (U1 :: Type -> Type))))

Methods

from :: DatatypeVariant -> Rep DatatypeVariant x Source #

to :: Rep DatatypeVariant x -> DatatypeVariant Source #

Read DatatypeVariant Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods readsPrec :: Int -> ReadS DatatypeVariant Source # readList :: ReadS [DatatypeVariant] Source # readPrec :: ReadPrec DatatypeVariant Source # readListPrec :: ReadPrec [DatatypeVariant] Source #
Show DatatypeVariant Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods showsPrec :: Int -> DatatypeVariant -> ShowS Source # show :: DatatypeVariant -> String Source # showList :: [DatatypeVariant] -> ShowS Source #
Eq DatatypeVariant Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods (==) :: DatatypeVariant -> DatatypeVariant -> Bool Source # (/=) :: DatatypeVariant -> DatatypeVariant -> Bool Source #
Ord DatatypeVariant Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

compare :: DatatypeVariant -> DatatypeVariant -> Ordering Source #

(<) :: DatatypeVariant -> DatatypeVariant -> Bool Source #

(<=) :: DatatypeVariant -> DatatypeVariant -> Bool Source #

(>) :: DatatypeVariant -> DatatypeVariant -> Bool Source #

(>=) :: DatatypeVariant -> DatatypeVariant -> Bool Source #

max :: DatatypeVariant -> DatatypeVariant -> DatatypeVariant Source #

min :: DatatypeVariant -> DatatypeVariant -> DatatypeVariant Source #

type Rep DatatypeVariant Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep DatatypeVariant = D1 ('MetaData "DatatypeVariant" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) ((C1 ('MetaCons "Datatype" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Newtype" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "DataInstance" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "NewtypeInstance" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "TypeData" 'PrefixI 'False) (U1 :: Type -> Type))))

data ConstructorVariant Source #

Possible variants of data constructors.

Constructors

NormalConstructor | Constructor without field names
InfixConstructor | Constructor without field names that is declared infix
RecordConstructor [Name] | Constructor with field names

#### Instances

Instances details

Data ConstructorVariant Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> ConstructorVariant -> c ConstructorVariant Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c ConstructorVariant Source #

toConstr :: ConstructorVariant -> Constr Source #

dataTypeOf :: ConstructorVariant -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c ConstructorVariant) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ConstructorVariant) Source #

gmapT :: (forall b. Data b => b -> b) -> ConstructorVariant -> ConstructorVariant Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> ConstructorVariant -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> ConstructorVariant -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> ConstructorVariant -> m ConstructorVariant Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> ConstructorVariant -> m ConstructorVariant Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> ConstructorVariant -> m ConstructorVariant Source #

Generic ConstructorVariant Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Associated Types

type Rep ConstructorVariant |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep ConstructorVariant = D1 ('MetaData "ConstructorVariant" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "NormalConstructor" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "InfixConstructor" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "RecordConstructor" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Name]))))

Methods

from :: ConstructorVariant -> Rep ConstructorVariant x Source #

to :: Rep ConstructorVariant x -> ConstructorVariant Source #

Show ConstructorVariant Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods showsPrec :: Int -> ConstructorVariant -> ShowS Source # show :: ConstructorVariant -> String Source # showList :: [ConstructorVariant] -> ShowS Source #
Eq ConstructorVariant Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods (==) :: ConstructorVariant -> ConstructorVariant -> Bool Source # (/=) :: ConstructorVariant -> ConstructorVariant -> Bool Source #
Ord ConstructorVariant Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

compare :: ConstructorVariant -> ConstructorVariant -> Ordering Source #

(<) :: ConstructorVariant -> ConstructorVariant -> Bool Source #

(<=) :: ConstructorVariant -> ConstructorVariant -> Bool Source #

(>) :: ConstructorVariant -> ConstructorVariant -> Bool Source #

(>=) :: ConstructorVariant -> ConstructorVariant -> Bool Source #

max :: ConstructorVariant -> ConstructorVariant -> ConstructorVariant Source #

min :: ConstructorVariant -> ConstructorVariant -> ConstructorVariant Source #

type Rep ConstructorVariant Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep ConstructorVariant = D1 ('MetaData "ConstructorVariant" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "NormalConstructor" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "InfixConstructor" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "RecordConstructor" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Name]))))

data FieldStrictness Source #

Normalized information about a constructor field's `UNPACK` and strictness annotations.

Note that the interface for reifying strictness in Template Haskell changed considerably in GHC 8.0. The presentation in this library mirrors that which can be found in GHC 8.0 or later, whereas previously, unpackedness and strictness were represented with a single data type:

    data Strict
      = IsStrict
      | NotStrict
      | Unpacked -- On GHC 7.4 or later

For backwards compatibility, we retrofit these constructors onto the following three values, respectively:

    isStrictAnnot  = FieldStrictness UnspecifiedUnpackedness Strict
    notStrictAnnot = FieldStrictness UnspecifiedUnpackedness UnspecifiedStrictness
    unpackedAnnot  = FieldStrictness Unpack Strict

Constructors

FieldStrictness |

Fields

- fieldUnpackedness :: Unpackedness
- fieldStrictness :: Strictness

#### Instances

Instances details

Data FieldStrictness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> FieldStrictness -> c FieldStrictness Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c FieldStrictness Source #

toConstr :: FieldStrictness -> Constr Source #

dataTypeOf :: FieldStrictness -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c FieldStrictness) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FieldStrictness) Source #

gmapT :: (forall b. Data b => b -> b) -> FieldStrictness -> FieldStrictness Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> FieldStrictness -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> FieldStrictness -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> FieldStrictness -> m FieldStrictness Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> FieldStrictness -> m FieldStrictness Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> FieldStrictness -> m FieldStrictness Source #

Generic FieldStrictness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Associated Types

type Rep FieldStrictness |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep FieldStrictness = D1 ('MetaData "FieldStrictness" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "FieldStrictness" 'PrefixI 'True) (S1 ('MetaSel ('Just "fieldUnpackedness") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Unpackedness) :*: S1 ('MetaSel ('Just "fieldStrictness") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Strictness)))

Methods

from :: FieldStrictness -> Rep FieldStrictness x Source #

to :: Rep FieldStrictness x -> FieldStrictness Source #

Show FieldStrictness Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods showsPrec :: Int -> FieldStrictness -> ShowS Source # show :: FieldStrictness -> String Source # showList :: [FieldStrictness] -> ShowS Source #
Eq FieldStrictness Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods (==) :: FieldStrictness -> FieldStrictness -> Bool Source # (/=) :: FieldStrictness -> FieldStrictness -> Bool Source #
Ord FieldStrictness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

compare :: FieldStrictness -> FieldStrictness -> Ordering Source #

(<) :: FieldStrictness -> FieldStrictness -> Bool Source #

(<=) :: FieldStrictness -> FieldStrictness -> Bool Source #

(>) :: FieldStrictness -> FieldStrictness -> Bool Source #

(>=) :: FieldStrictness -> FieldStrictness -> Bool Source #

max :: FieldStrictness -> FieldStrictness -> FieldStrictness Source #

min :: FieldStrictness -> FieldStrictness -> FieldStrictness Source #

type Rep FieldStrictness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep FieldStrictness = D1 ('MetaData "FieldStrictness" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "FieldStrictness" 'PrefixI 'True) (S1 ('MetaSel ('Just "fieldUnpackedness") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Unpackedness) :*: S1 ('MetaSel ('Just "fieldStrictness") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Strictness)))

data Unpackedness Source #

Information about a constructor field's unpackedness annotation.

Constructors

UnspecifiedUnpackedness | No annotation whatsoever
NoUnpack | Annotated with `{-# NOUNPACK #-}`
Unpack | Annotated with `{-# UNPACK #-}`

#### Instances

Instances details

Data Unpackedness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Unpackedness -> c Unpackedness Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Unpackedness Source #

toConstr :: Unpackedness -> Constr Source #

dataTypeOf :: Unpackedness -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Unpackedness) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Unpackedness) Source #

gmapT :: (forall b. Data b => b -> b) -> Unpackedness -> Unpackedness Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> Unpackedness -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Unpackedness -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness Source #

Generic Unpackedness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Associated Types

type Rep Unpackedness |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep Unpackedness = D1 ('MetaData "Unpackedness" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "UnspecifiedUnpackedness" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "NoUnpack" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Unpack" 'PrefixI 'False) (U1 :: Type -> Type)))

Methods

from :: Unpackedness -> Rep Unpackedness x Source #

to :: Rep Unpackedness x -> Unpackedness Source #

Show Unpackedness Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods showsPrec :: Int -> Unpackedness -> ShowS Source # show :: Unpackedness -> String Source # showList :: [Unpackedness] -> ShowS Source #
Eq Unpackedness Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods (==) :: Unpackedness -> Unpackedness -> Bool Source # (/=) :: Unpackedness -> Unpackedness -> Bool Source #
Ord Unpackedness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

compare :: Unpackedness -> Unpackedness -> Ordering Source #

(<) :: Unpackedness -> Unpackedness -> Bool Source #

(<=) :: Unpackedness -> Unpackedness -> Bool Source #

(>) :: Unpackedness -> Unpackedness -> Bool Source #

(>=) :: Unpackedness -> Unpackedness -> Bool Source #

max :: Unpackedness -> Unpackedness -> Unpackedness Source #

min :: Unpackedness -> Unpackedness -> Unpackedness Source #

type Rep Unpackedness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

type Rep Unpackedness = D1 ('MetaData "Unpackedness" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "UnspecifiedUnpackedness" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "NoUnpack" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Unpack" 'PrefixI 'False) (U1 :: Type -> Type)))

data Strictness Source #

Information about a constructor field's strictness annotation.

Constructors

UnspecifiedStrictness | No annotation whatsoever
Lazy | Annotated with `~`
Strict | Annotated with `!`

#### Instances

Instances details

Data Strictness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Strictness -> c Strictness Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Strictness Source #

toConstr :: Strictness -> Constr Source #

dataTypeOf :: Strictness -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Strictness) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Strictness) Source #

gmapT :: (forall b. Data b => b -> b) -> Strictness -> Strictness Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Strictness -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Strictness -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> Strictness -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Strictness -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Strictness -> m Strictness Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Strictness -> m Strictness Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Strictness -> m Strictness Source #

Generic Strictness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Associated Types

type Rep Strictness |
Instance details Defined in Language.Haskell.TH.Datatype type Rep Strictness = D1 ('MetaData "Strictness" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "UnspecifiedStrictness" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Lazy" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Strict" 'PrefixI 'False) (U1 :: Type -> Type)))

Methods

from :: Strictness -> Rep Strictness x Source #

to :: Rep Strictness x -> Strictness Source #

Show Strictness Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods showsPrec :: Int -> Strictness -> ShowS Source # show :: Strictness -> String Source # showList :: [Strictness] -> ShowS Source #
Eq Strictness Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods (==) :: Strictness -> Strictness -> Bool Source # (/=) :: Strictness -> Strictness -> Bool Source #
Ord Strictness Source # |

Instance details

Defined in Language.Haskell.TH.Datatype

Methods

compare :: Strictness -> Strictness -> Ordering Source #

(<) :: Strictness -> Strictness -> Bool Source #

(<=) :: Strictness -> Strictness -> Bool Source #

(>) :: Strictness -> Strictness -> Bool Source #

(>=) :: Strictness -> Strictness -> Bool Source #

max :: Strictness -> Strictness -> Strictness Source #

min :: Strictness -> Strictness -> Strictness Source #

type Rep Strictness Source # |
Instance details Defined in Language.Haskell.TH.Datatype type Rep Strictness = D1 ('MetaData "Strictness" "Language.Haskell.TH.Datatype" "th-abstraction-0.7.1.0-4pMh4c52Vfc8WxXdjHtZwz" 'False) (C1 ('MetaCons "UnspecifiedStrictness" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Lazy" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Strict" 'PrefixI 'False) (U1 :: Type -> Type)))

# Normalization functions

reifyDatatype Source #

Arguments

:: Name | data type or constructor name
-> Q DatatypeInfo |

Compute a normalized view of the metadata about a data type or newtype given a constructor.

This function will accept any constructor (value or type) for a type declared with newtype or data. Value constructors must be used to lookup datatype information about data instances and newtype instances, as giving the type constructor of a data family is often not enough to determine a particular data family instance.

In addition, this function will also accept a record selector for a data type with a constructor which uses that record.

GADT constructors are normalized into datatypes with explicit equality constraints. Note that no effort is made to distinguish between equalities of the same (homogeneous) kind and equalities between different (heterogeneous) kinds. For instance, the following GADT's constructors:

    data T (a :: k -> *) where
      MkT1 :: T Proxy
      MkT2 :: T Maybe

will be normalized to the following equality constraints:

    AppT (AppT EqualityT (VarT a)) (ConT Proxy) -- MkT1
    AppT (AppT EqualityT (VarT a)) (ConT Maybe) -- MkT2

But only the first equality constraint is well kinded, since in the second constraint, the kinds of `(a :: k -> *)` and `(Maybe :: * -> *)` are different. Trying to categorize which constraints need homogeneous or heterogeneous equality is tricky, so we leave that task to users of this library.

Primitive types (other than unboxed sums and tuples) will have no `datatypeCons` in their normalization.

This function will apply various bug-fixes to the output of the underlying `template-haskell` library in order to provide a view of datatypes in as uniform a way as possible.

reifyConstructor Source #

Arguments

:: Name | constructor name
-> Q ConstructorInfo |

Compute a normalized view of the metadata about a constructor given its `Name`. This is useful for scenarios when you don't care about the info for the enclosing data type.

reifyRecord Source #

Arguments

:: Name | record name
-> Q ConstructorInfo |

Compute a normalized view of the metadata about a constructor given the `Name` of one of its record selectors. This is useful for scenarios when you don't care about the info for the enclosing data type.

normalizeInfo :: Info -> Q DatatypeInfo Source #

Normalize `Info` for a newtype or datatype into a `DatatypeInfo`. Fail in `Q` otherwise.

normalizeDec :: Dec -> Q DatatypeInfo Source #

Normalize `Dec` for a newtype or datatype into a `DatatypeInfo`. Fail in `Q` otherwise.

Beware: `normalizeDec` can have surprising behavior when it comes to fixity. For instance, if you have this quasiquoted data declaration:

    [d| infix 5 :^^:
        data Foo where
          (:^^:) :: Int -> Int -> Foo |]

Then if you pass the `Dec` for `Foo` to `normalizeDec` without splicing it in a previous Template Haskell splice, then `(:^^:)` will be labeled a `NormalConstructor` instead of an `InfixConstructor`. This is because Template Haskell has no way to reify the fixity declaration for `(:^^:)`, so it must assume there isn't one. To work around this behavior, use `reifyDatatype` instead.

normalizeCon Source #

Arguments

:: Name | Type constructor
-> [TyVarBndrUnit] | Type parameters
-> [Type] | Argument types
-> Kind | Result kind
-> DatatypeVariant | Extra information
-> Con | Constructor
-> Q [ConstructorInfo] |

Normalize a `Con` into a `ConstructorInfo`. This requires knowledge of the type and parameters of the constructor, as well as whether the constructor is for a data family instance, as extracted from the outer `Dec`.

# `DatatypeInfo` lookup functions

lookupByConstructorName Source #

Arguments

:: Name | constructor name
-> DatatypeInfo | info for the datatype which has that constructor
-> ConstructorInfo |

Given a `DatatypeInfo`, find the `ConstructorInfo` corresponding to the `Name` of one of its constructors.

lookupByRecordName Source #

Arguments

:: Name | record name
-> DatatypeInfo | info for the datatype which has that constructor
-> ConstructorInfo |

Given a `DatatypeInfo`, find the `ConstructorInfo` corresponding to the `Name` of one of its constructors.

# Type variable manipulation

class TypeSubstitution a where Source #

Class for types that support type variable substitution.

Methods

applySubstitution :: Map Name Type -> a -> a Source #

Apply a type variable substitution.

freeVariables :: a -> [Name] Source #

Compute the free type variables

#### Instances

Instances details

TypeSubstitution Type Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods applySubstitution :: Map Name Type -> Type -> Type Source # freeVariables :: Type -> [Name] Source #
TypeSubstitution ConstructorInfo Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods applySubstitution :: Map Name Type -> ConstructorInfo -> ConstructorInfo Source # freeVariables :: ConstructorInfo -> [Name] Source #
TypeSubstitution a => TypeSubstitution [a] Source # |
Instance details Defined in Language.Haskell.TH.Datatype Methods applySubstitution :: Map Name Type -> [a] -> [a] Source # freeVariables :: [a] -> [Name] Source #

quantifyType :: Type -> Type Source #

Add universal quantifier for all free variables in the type. This is useful when constructing a type signature for a declaration. This code is careful to ensure that the order of the variables quantified is determined by their order of appearance in the type signature. (In contrast with being dependent upon the Ord instance for `Name`)

freeVariablesWellScoped :: [Type] -> [TyVarBndrUnit] Source #

Take a list of `Type`s, find their free variables, and sort them according to dependency order.

As an example of how this function works, consider the following type:

    Proxy (a :: k)

Calling `freeVariables` on this type would yield `[a, k]`, since that is the order in which those variables appear in a left-to-right fashion. But this order does not preserve the fact that `k` is the kind of `a`. Moreover, if you tried writing the type `forall a k. Proxy (a :: k)`, GHC would reject this, since GHC would demand that `k` come before `a`.

`freeVariablesWellScoped` orders the free variables of a type in a way that preserves this dependency ordering. If one were to call `freeVariablesWellScoped` on the type above, it would return `[k, (a :: k)]`. (This is why `freeVariablesWellScoped` returns a list of `TyVarBndr`s instead of `Name`s, since it must make it explicit that `k` is the kind of `a`.)

`freeVariablesWellScoped` guarantees the free variables returned will be ordered such that:

1. Whenever an explicit kind signature of the form `(A :: K)` is encountered, the free variables of `K` will always appear to the left of the free variables of `A` in the returned result.
2. The constraint in (1) notwithstanding, free variables will appear in left-to-right order of their original appearance.

On older GHCs, this takes measures to avoid returning explicitly bound kind variables, which was not possible before `TypeInType`.

freshenFreeVariables :: Type -> Q Type Source #

Substitute all of the free variables in a type with fresh ones

# `Pred` functions

equalPred :: Type -> Type -> Pred Source #

Construct an equality constraint. The implementation of `Pred` varies across versions of Template Haskell.

classPred Source #

Arguments

:: Name | class
-> [Type] | parameters
-> Pred |

Construct a typeclass constraint. The implementation of `Pred` varies across versions of Template Haskell.

asEqualPred :: Pred -> Maybe (Type, Type) Source #

Match a `Pred` representing an equality constraint. Returns arguments to the equality constraint if successful.

asClassPred :: Pred -> Maybe (Name, [Type]) Source #

Match a `Pred` representing a class constraint. Returns the classname and parameters if successful.

# Backward compatible data definitions

dataDCompat Source #

Arguments

:: CxtQ | context
-> Name | type constructor
-> [TyVarBndrVis] | type parameters
-> [ConQ] | constructor definitions
-> [Name] | derived class names
-> DecQ |

Backward compatible version of `dataD`

newtypeDCompat Source #

Arguments

:: CxtQ | context
-> Name | type constructor
-> [TyVarBndrVis] | type parameters
-> ConQ | constructor definition
-> [Name] | derived class names
-> DecQ |

Backward compatible version of `newtypeD`

tySynInstDCompat Source #

Arguments

:: Name | type family name
-> Maybe [Q TyVarBndrUnit] | type variable binders
-> [TypeQ] | instance parameters
-> TypeQ | instance result
-> DecQ |

Backward compatible version of `tySynInstD`

pragLineDCompat Source #

Arguments

:: Int | line number
-> String | file name
-> Maybe DecQ |

Backward compatible version of `pragLineD`. Returns `Nothing` if line pragmas are not suported.

arrowKCompat :: Kind -> Kind -> Kind Source #

# Strictness annotations

isStrictAnnot :: FieldStrictness Source #

notStrictAnnot :: FieldStrictness Source #

unpackedAnnot :: FieldStrictness Source #

# Type simplification

resolveTypeSynonyms :: Type -> Q Type Source #

Expand all of the type synonyms in a type.

Note that this function will drop parentheses as a side effect.

resolveKindSynonyms :: Kind -> Q Kind Source #

Expand all of the type synonyms in a `Kind`.

resolvePredSynonyms :: Pred -> Q Pred Source #

Expand all of the type synonyms in a `Pred`.

resolveInfixT :: Type -> Q Type Source #

Resolve any infix type application in a type using the fixities that are currently available. Starting in `template-haskell-2.11` types could contain unresolved infix applications.

# Fixities

reifyFixityCompat :: Name -> Q (Maybe Fixity) Source #

Backwards compatibility wrapper for `Fixity` lookup.

In `template-haskell-2.11.0.0` and later, the answer will always be `Just` of a fixity.

Before `template-haskell-2.11.0.0` it was only possible to determine fixity information for variables, class methods, and data constructors. In this case for type operators the answer could be `Nothing`, which indicates that the answer is unavailable.

showFixity :: Fixity -> String Source #

Render a `Fixity` as it would appear in Haskell source.

Example: `infixl 5`

showFixityDirection :: FixityDirection -> String Source #

Render a `FixityDirection` like it would appear in Haskell source.

Examples: `infixl` `infixr` `infix`

# Convenience functions

unifyTypes :: [Type] -> Q (Map Name Type) Source #

Compute the type variable substitution that unifies a list of types, or fail in `Q`.

All infix issue should be resolved before using `unifyTypes`

Alpha equivalent quantified types are not unified.

tvName :: TyVarBndr_ flag -> Name Source #

Extract the type variable name from a `TyVarBndr`, ignoring the kind signature if one exists.

tvKind :: TyVarBndr_ flag -> Kind Source #

Extract the kind from a `TyVarBndr`. Assumes `PlainTV` has kind `*`.

datatypeType :: DatatypeInfo -> Type Source #

Construct a Type using the datatype's type constructor and type parameters. Kind signatures are removed.