Copyright | (C) 2014 Richard Eisenberg |
---|---|
License | BSD-style (see LICENSE) |
Maintainer | Ryan Scott |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Desugars full Template Haskell syntax into a smaller core syntax for further processing.
Synopsis
- data DExp
- data DLetDec
- data DPat
- data DType
- data ForallVisFlag
- type DKind = DType
- type DCxt = [DPred]
- type DPred = DType
- data DTyVarBndr
- data DMatch = DMatch DPat DExp
- data DClause = DClause [DPat] DExp
- data DDec
- = DLetDec DLetDec
- | DDataD NewOrData DCxt Name [DTyVarBndr] (Maybe DKind) [DCon] [DDerivClause]
- | DTySynD Name [DTyVarBndr] DType
- | DClassD DCxt Name [DTyVarBndr] [FunDep] [DDec]
- | DInstanceD (Maybe Overlap) (Maybe [DTyVarBndr]) DCxt DType [DDec]
- | DForeignD DForeign
- | DOpenTypeFamilyD DTypeFamilyHead
- | DClosedTypeFamilyD DTypeFamilyHead [DTySynEqn]
- | DDataFamilyD Name [DTyVarBndr] (Maybe DKind)
- | DDataInstD NewOrData DCxt (Maybe [DTyVarBndr]) DType (Maybe DKind) [DCon] [DDerivClause]
- | DTySynInstD DTySynEqn
- | DRoleAnnotD Name [Role]
- | DStandaloneDerivD (Maybe DDerivStrategy) (Maybe [DTyVarBndr]) DCxt DType
- | DDefaultSigD Name DType
- | DPatSynD Name PatSynArgs DPatSynDir DPat
- | DPatSynSigD Name DPatSynType
- | DKiSigD Name DKind
- data DDerivClause = DDerivClause (Maybe DDerivStrategy) DCxt
- data DDerivStrategy
- data DPatSynDir
- = DUnidir
- | DImplBidir
- | DExplBidir [DClause]
- type DPatSynType = DType
- data Overlap
- data PatSynArgs
- = PrefixPatSyn [Name]
- | InfixPatSyn Name Name
- | RecordPatSyn [Name]
- data NewOrData
- data DTypeFamilyHead = DTypeFamilyHead Name [DTyVarBndr] DFamilyResultSig (Maybe InjectivityAnn)
- data DFamilyResultSig
- data InjectivityAnn = InjectivityAnn Name [Name]
- data DCon = DCon [DTyVarBndr] DCxt Name DConFields DType
- data DConFields
- type DDeclaredInfix = Bool
- type DBangType = (Bang, DType)
- type DVarBangType = (Name, Bang, DType)
- data Bang = Bang SourceUnpackedness SourceStrictness
- data SourceUnpackedness
- data SourceStrictness
- data DForeign
- data DPragma
- data DRuleBndr
- data DTySynEqn = DTySynEqn (Maybe [DTyVarBndr]) DType DType
- data DInfo
- type DInstanceDec = DDec
- data Role
- data AnnTarget
- class Desugar th ds | ds -> th where
- dsExp :: DsMonad q => Exp -> q DExp
- dsDecs :: DsMonad q => [Dec] -> q [DDec]
- dsType :: DsMonad q => Type -> q DType
- dsInfo :: DsMonad q => Info -> q DInfo
- dsPatOverExp :: DsMonad q => Pat -> DExp -> q (DPat, DExp)
- dsPatsOverExp :: DsMonad q => [Pat] -> DExp -> q ([DPat], DExp)
- dsPatX :: DsMonad q => Pat -> q (DPat, [(Name, DExp)])
- dsLetDecs :: DsMonad q => [Dec] -> q ([DLetDec], DExp -> DExp)
- dsTvb :: DsMonad q => TyVarBndr -> q DTyVarBndr
- dsCxt :: DsMonad q => Cxt -> q DCxt
- dsCon :: DsMonad q => [DTyVarBndr] -> DType -> Con -> q [DCon]
- dsForeign :: DsMonad q => Foreign -> q DForeign
- dsPragma :: DsMonad q => Pragma -> q DPragma
- dsRuleBndr :: DsMonad q => RuleBndr -> q DRuleBndr
- type PatM q = WriterT [(Name, DExp)] q
- dsPred :: DsMonad q => Pred -> q DCxt
- dsPat :: DsMonad q => Pat -> PatM q DPat
- dsDec :: DsMonad q => Dec -> q [DDec]
- dsDataDec :: DsMonad q => NewOrData -> Cxt -> Name -> [TyVarBndr] -> Maybe Kind -> [Con] -> [DerivingClause] -> q [DDec]
- dsDataInstDec :: DsMonad q => NewOrData -> Cxt -> Name -> Maybe [TyVarBndr] -> [TypeArg] -> Maybe Kind -> [Con] -> [DerivingClause] -> q [DDec]
- type DerivingClause = DerivClause
- dsDerivClause :: DsMonad q => DerivingClause -> q DDerivClause
- dsLetDec :: DsMonad q => Dec -> q ([DLetDec], DExp -> DExp)
- dsMatches :: DsMonad q => Name -> [Match] -> q [DMatch]
- dsBody :: DsMonad q => Body -> [Dec] -> DExp -> q DExp
- dsGuards :: DsMonad q => [(Guard, Exp)] -> DExp -> q DExp
- dsDoStmts :: DsMonad q => [Stmt] -> q DExp
- dsComp :: DsMonad q => [Stmt] -> q DExp
- dsClauses :: DsMonad q => Name -> [Clause] -> q [DClause]
- dsBangType :: DsMonad q => BangType -> q DBangType
- dsVarBangType :: DsMonad q => VarBangType -> q DVarBangType
- dsTypeFamilyHead :: DsMonad q => TypeFamilyHead -> q DTypeFamilyHead
- dsFamilyResultSig :: DsMonad q => FamilyResultSig -> q DFamilyResultSig
- dsPatSynDir :: DsMonad q => Name -> PatSynDir -> q DPatSynDir
- dsTypeArg :: DsMonad q => TypeArg -> q DTypeArg
- module Language.Haskell.TH.Desugar.Sweeten
- expand :: (DsMonad q, Data a) => a -> q a
- expandType :: DsMonad q => DType -> q DType
- reifyWithWarning :: (Quasi q, MonadFail q) => Name -> q Info
- withLocalDeclarations :: DsMonad q => [Dec] -> DsM q a -> q a
- dsReify :: DsMonad q => Name -> q (Maybe DInfo)
- dsReifyType :: DsMonad q => Name -> q (Maybe DType)
- reifyWithLocals_maybe :: DsMonad q => Name -> q (Maybe Info)
- reifyWithLocals :: DsMonad q => Name -> q Info
- reifyFixityWithLocals :: DsMonad q => Name -> q (Maybe Fixity)
- reifyTypeWithLocals_maybe :: DsMonad q => Name -> q (Maybe Type)
- reifyTypeWithLocals :: DsMonad q => Name -> q Type
- lookupValueNameWithLocals :: DsMonad q => String -> q (Maybe Name)
- lookupTypeNameWithLocals :: DsMonad q => String -> q (Maybe Name)
- mkDataNameWithLocals :: DsMonad q => String -> q Name
- mkTypeNameWithLocals :: DsMonad q => String -> q Name
- reifyNameSpace :: DsMonad q => Name -> q (Maybe NameSpace)
- class (Quasi m, MonadFail m) => DsMonad m where
- localDeclarations :: m [Dec]
- data DsM q a
- scExp :: DsMonad q => DExp -> q DExp
- scLetDec :: DsMonad q => DLetDec -> q DLetDec
- module Language.Haskell.TH.Desugar.Subst
- fvDType :: DType -> OSet Name
- extractBoundNamesDPat :: DPat -> OSet Name
- applyDExp :: DExp -> [DExp] -> DExp
- dPatToDExp :: DPat -> DExp
- removeWilds :: DsMonad q => DPat -> q DPat
- getDataD :: DsMonad q => String -> Name -> q ([TyVarBndr], [Con])
- dataConNameToDataName :: DsMonad q => Name -> q Name
- dataConNameToCon :: DsMonad q => Name -> q Con
- nameOccursIn :: Data a => Name -> a -> Bool
- allNamesIn :: Data a => a -> [Name]
- flattenDValD :: Quasi q => DLetDec -> q [DLetDec]
- getRecordSelectors :: DsMonad q => DType -> [DCon] -> q [DLetDec]
- mkTypeName :: Quasi q => String -> q Name
- mkDataName :: Quasi q => String -> q Name
- newUniqueName :: Quasi q => String -> q Name
- mkTupleDExp :: [DExp] -> DExp
- mkTupleDPat :: [DPat] -> DPat
- maybeDLetE :: [DLetDec] -> DExp -> DExp
- maybeDCaseE :: String -> DExp -> [DMatch] -> DExp
- mkDLamEFromDPats :: DsMonad q => [DPat] -> DExp -> q DExp
- tupleDegree_maybe :: String -> Maybe Int
- tupleNameDegree_maybe :: Name -> Maybe Int
- unboxedSumDegree_maybe :: String -> Maybe Int
- unboxedSumNameDegree_maybe :: Name -> Maybe Int
- unboxedTupleDegree_maybe :: String -> Maybe Int
- unboxedTupleNameDegree_maybe :: Name -> Maybe Int
- strictToBang :: Bang -> Bang
- isTypeKindName :: Name -> Bool
- typeKindName :: Name
- bindIP :: forall name a r. a -> (IP name a => r) -> r
- conExistentialTvbs :: DsMonad q => DType -> DCon -> q [DTyVarBndr]
- mkExtraDKindBinders :: forall q. DsMonad q => DKind -> q [DTyVarBndr]
- dTyVarBndrToDType :: DTyVarBndr -> DType
- toposortTyVarsOf :: [DType] -> [DTyVarBndr]
- data FunArgs
- data VisFunArg
- filterVisFunArgs :: FunArgs -> [VisFunArg]
- ravelType :: FunArgs -> Type -> Type
- unravelType :: Type -> (FunArgs, Type)
- data DFunArgs
- data DVisFunArg
- filterDVisFunArgs :: DFunArgs -> [DVisFunArg]
- ravelDType :: DFunArgs -> DType -> DType
- unravelDType :: DType -> (DFunArgs, DType)
- data TypeArg
- applyType :: Type -> [TypeArg] -> Type
- filterTANormals :: [TypeArg] -> [Type]
- unfoldType :: Type -> (Type, [TypeArg])
- data DTypeArg
- applyDType :: DType -> [DTypeArg] -> DType
- filterDTANormals :: [DTypeArg] -> [DType]
- unfoldDType :: DType -> (DType, [DTypeArg])
- extractBoundNamesStmt :: Stmt -> OSet Name
- extractBoundNamesDec :: Dec -> OSet Name
- extractBoundNamesPat :: Pat -> OSet Name
Desugared data types
Corresponds to TH's Exp
type. Note that DLamE
takes names, not patterns.
DVarE Name | |
DConE Name | |
DLitE Lit | |
DAppE DExp DExp | |
DAppTypeE DExp DType | |
DLamE [Name] DExp | |
DCaseE DExp [DMatch] | |
DLetE [DLetDec] DExp | |
DSigE DExp DType | |
DStaticE DExp |
Instances
Declarations as used in a let
statement.
Instances
Corresponds to TH's Pat
type.
Instances
Corresponds to TH's Type
type, used to represent
types and kinds.
DForallT ForallVisFlag [DTyVarBndr] DType | |
DConstrainedT DCxt DType | |
DAppT DType DType | |
DAppKindT DType DKind | |
DSigT DType DKind | |
DVarT Name | |
DConT Name | |
DArrowT | |
DLitT TyLit | |
DWildCardT |
Instances
data ForallVisFlag Source #
Is a forall
invisible (e.g., forall a b. {...}
, with a dot) or visible
(e.g., forall a b -> {...}
, with an arrow)?
ForallVis | A visible |
ForallInvis | An invisible |
Instances
data DTyVarBndr Source #
Corresponds to TH's TyVarBndr
Instances
Corresponds to TH's Match
type.
Instances
Eq DMatch Source # | |
Data DMatch Source # | |
Defined in Language.Haskell.TH.Desugar.AST gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> DMatch -> c DMatch # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c DMatch # toConstr :: DMatch -> Constr # dataTypeOf :: DMatch -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c DMatch) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DMatch) # gmapT :: (forall b. Data b => b -> b) -> DMatch -> DMatch # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> DMatch -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> DMatch -> r # gmapQ :: (forall d. Data d => d -> u) -> DMatch -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> DMatch -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> DMatch -> m DMatch # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> DMatch -> m DMatch # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> DMatch -> m DMatch # | |
Show DMatch Source # | |
Generic DMatch Source # | |
Lift DMatch Source # | |
type Rep DMatch Source # | |
Defined in Language.Haskell.TH.Desugar.AST type Rep DMatch = D1 (MetaData "DMatch" "Language.Haskell.TH.Desugar.AST" "th-desugar-1.11-6CeS211oN4bGxRJRLZG2AP" False) (C1 (MetaCons "DMatch" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 DPat) :*: S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 DExp))) |
Corresponds to TH's Clause
type.
Instances
Eq DClause Source # | |
Data DClause Source # | |
Defined in Language.Haskell.TH.Desugar.AST gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> DClause -> c DClause # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c DClause # toConstr :: DClause -> Constr # dataTypeOf :: DClause -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c DClause) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DClause) # gmapT :: (forall b. Data b => b -> b) -> DClause -> DClause # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> DClause -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> DClause -> r # gmapQ :: (forall d. Data d => d -> u) -> DClause -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> DClause -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> DClause -> m DClause # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> DClause -> m DClause # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> DClause -> m DClause # | |
Show DClause Source # | |
Generic DClause Source # | |
Lift DClause Source # | |
type Rep DClause Source # | |
Defined in Language.Haskell.TH.Desugar.AST type Rep DClause = D1 (MetaData "DClause" "Language.Haskell.TH.Desugar.AST" "th-desugar-1.11-6CeS211oN4bGxRJRLZG2AP" False) (C1 (MetaCons "DClause" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [DPat]) :*: S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 DExp))) |
Corresponds to TH's Dec
type.
Instances
data DDerivClause Source #
Corresponds to TH's DerivClause
type.
Instances
data DDerivStrategy Source #
Corresponds to TH's DerivStrategy
type.
DStockStrategy | A "standard" derived instance |
DAnyclassStrategy | -XDeriveAnyClass |
DNewtypeStrategy | -XGeneralizedNewtypeDeriving |
DViaStrategy DType | -XDerivingVia |
Instances
data DPatSynDir Source #
Corresponds to TH's PatSynDir
type
DUnidir | pattern P x {<-} p |
DImplBidir | pattern P x {=} p |
DExplBidir [DClause] | pattern P x {<-} p where P x = e |
Instances
type DPatSynType = DType Source #
Corresponds to TH's PatSynType
type
Varieties of allowed instance overlap.
Overlappable | May be overlapped by more specific instances |
Overlapping | May overlap a more general instance |
Overlaps | Both |
Incoherent | Both |
Instances
Eq Overlap | |
Data Overlap | |
Defined in Language.Haskell.TH.Syntax gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Overlap -> c Overlap # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Overlap # toConstr :: Overlap -> Constr # dataTypeOf :: Overlap -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Overlap) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Overlap) # gmapT :: (forall b. Data b => b -> b) -> Overlap -> Overlap # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Overlap -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Overlap -> r # gmapQ :: (forall d. Data d => d -> u) -> Overlap -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Overlap -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Overlap -> m Overlap # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Overlap -> m Overlap # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Overlap -> m Overlap # | |
Ord Overlap | |
Show Overlap | |
Generic Overlap | |
type Rep Overlap | |
Defined in Language.Haskell.TH.Syntax type Rep Overlap = D1 (MetaData "Overlap" "Language.Haskell.TH.Syntax" "template-haskell" False) ((C1 (MetaCons "Overlappable" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "Overlapping" PrefixI False) (U1 :: Type -> Type)) :+: (C1 (MetaCons "Overlaps" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "Incoherent" PrefixI False) (U1 :: Type -> Type))) |
data PatSynArgs #
A pattern synonym's argument type.
PrefixPatSyn [Name] | pattern P {x y z} = p |
InfixPatSyn Name Name | pattern {x P y} = p |
RecordPatSyn [Name] | pattern P { {x,y,z} } = p |
Instances
Is it a newtype
or a data
type?
Instances
Eq NewOrData Source # | |
Data NewOrData Source # | |
Defined in Language.Haskell.TH.Desugar.AST gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> NewOrData -> c NewOrData # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c NewOrData # toConstr :: NewOrData -> Constr # dataTypeOf :: NewOrData -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c NewOrData) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NewOrData) # gmapT :: (forall b. Data b => b -> b) -> NewOrData -> NewOrData # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NewOrData -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NewOrData -> r # gmapQ :: (forall d. Data d => d -> u) -> NewOrData -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> NewOrData -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> NewOrData -> m NewOrData # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> NewOrData -> m NewOrData # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> NewOrData -> m NewOrData # | |
Show NewOrData Source # | |
Generic NewOrData Source # | |
Lift NewOrData Source # | |
type Rep NewOrData Source # | |
data DTypeFamilyHead Source #
Corresponds to TH's TypeFamilyHead
type
Instances
data DFamilyResultSig Source #
Corresponds to TH's FamilyResultSig
type
Instances
data InjectivityAnn #
Injectivity annotation
Instances
Corresponds to TH's Con
type. Unlike Con
, all DCon
s reflect GADT
syntax. This is beneficial for th-desugar
's since it means
that all data type declarations can support explicit return kinds, so
one does not need to represent them with something like
,
since Haskell98-style data declaration syntax isn't used. Accordingly,
there are some differences between Maybe
DKind
DCon
and Con
to keep in mind:
- Unlike
ForallC
, where the meaning of theTyVarBndr
s changes depending on whether it's followed by 'GadtC'/'RecGadtC' or not, the meaning of theDTyVarBndr
s in aDCon
is always the same: it is the list of universally and existentially quantified type variables. Note that it is not guaranteed that one set of type variables will appear before the other. - A
DCon
always has an explicit return type.
DCon [DTyVarBndr] DCxt Name DConFields DType | The GADT result type |
Instances
data DConFields Source #
A list of fields either for a standard data constructor or a record data constructor.
Instances
type DDeclaredInfix = Bool Source #
True
if a constructor is declared infix. For normal ADTs, this means
that is was written in infix style. For example, both of the constructors
below are declared infix.
data Infix = Int Fixity
Int | Int :*: Int
Whereas neither of these constructors are declared infix:
data Prefix = Prefix Int Int | (:+:) Int Int
For GADTs, detecting whether a constructor is declared infix is a bit trickier, as one cannot write a GADT constructor "infix-style" like one can for normal ADT constructors. GHC considers a GADT constructor to be declared infix if it meets the following three criteria:
- Its name uses operator syntax (e.g.,
(:*:)
). - It has exactly two fields (without record syntax).
- It has a programmer-specified fixity declaration.
For example, in the following GADT:
infixl 5 :**:, :&&:, :^^:, ActuallyPrefix
data InfixGADT a where
(:**:) :: Int -> b -> InfixGADT (Maybe b) -- Only this one is infix
ActuallyPrefix :: Char -> Bool -> InfixGADT Double
(:&&:) :: { infixGADT1 :: b, infixGADT2 :: Int } -> InfixGADT b :: Int -> Int -> Int -> InfixGADT Int
(:!!:) :: Char -> Char -> InfixGADT Char
Only the (:**:)
constructor is declared infix. The other constructors
are not declared infix, because:
ActuallyPrefix
does not use operator syntax (criterion 1).(:&&:)
uses record syntax (criterion 2).(:^^:)
does not have exactly two fields (criterion 2).(:!!:)
does not have a programmer-specified fixity declaration (criterion 3).
Bang SourceUnpackedness SourceStrictness | C { {-# UNPACK #-} !}a |
Instances
Eq Bang | |
Data Bang | |
Defined in Language.Haskell.TH.Syntax gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Bang -> c Bang # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Bang # dataTypeOf :: Bang -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Bang) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Bang) # gmapT :: (forall b. Data b => b -> b) -> Bang -> Bang # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Bang -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Bang -> r # gmapQ :: (forall d. Data d => d -> u) -> Bang -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Bang -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Bang -> m Bang # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Bang -> m Bang # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Bang -> m Bang # | |
Ord Bang | |
Show Bang | |
Generic Bang | |
Ppr Bang | |
type Rep Bang | |
Defined in Language.Haskell.TH.Syntax type Rep Bang = D1 (MetaData "Bang" "Language.Haskell.TH.Syntax" "template-haskell" False) (C1 (MetaCons "Bang" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 SourceUnpackedness) :*: S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 SourceStrictness))) |
data SourceUnpackedness #
NoSourceUnpackedness | C a |
SourceNoUnpack | C { {-# NOUNPACK #-} } a |
SourceUnpack | C { {-# UNPACK #-} } a |
Instances
data SourceStrictness #
NoSourceStrictness | C a |
SourceLazy | C {~}a |
SourceStrict | C {!}a |
Instances
Corresponds to TH's Foreign
type.
Instances
Corresponds to TH's Pragma
type.
Instances
Corresponds to TH's RuleBndr
type.
Instances
Eq DRuleBndr Source # | |
Data DRuleBndr Source # | |
Defined in Language.Haskell.TH.Desugar.AST gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> DRuleBndr -> c DRuleBndr # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c DRuleBndr # toConstr :: DRuleBndr -> Constr # dataTypeOf :: DRuleBndr -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c DRuleBndr) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DRuleBndr) # gmapT :: (forall b. Data b => b -> b) -> DRuleBndr -> DRuleBndr # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> DRuleBndr -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> DRuleBndr -> r # gmapQ :: (forall d. Data d => d -> u) -> DRuleBndr -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> DRuleBndr -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> DRuleBndr -> m DRuleBndr # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> DRuleBndr -> m DRuleBndr # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> DRuleBndr -> m DRuleBndr # | |
Show DRuleBndr Source # | |
Generic DRuleBndr Source # | |
Lift DRuleBndr Source # | |
type Rep DRuleBndr Source # | |
Defined in Language.Haskell.TH.Desugar.AST type Rep DRuleBndr = D1 (MetaData "DRuleBndr" "Language.Haskell.TH.Desugar.AST" "th-desugar-1.11-6CeS211oN4bGxRJRLZG2AP" False) (C1 (MetaCons "DRuleVar" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Name)) :+: C1 (MetaCons "DTypedRuleVar" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Name) :*: S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 DType))) |
Corresponds to TH's TySynEqn
type (to store type family equations).
Instances
Corresponds to TH's Info
type.
DTyConI DDec (Maybe [DInstanceDec]) | |
DVarI Name DType (Maybe Name) | The |
DTyVarI Name DKind | |
DPrimTyConI Name Int Bool | The |
DPatSynI Name DPatSynType |
Instances
type DInstanceDec Source #
= DDec | Guaranteed to be an instance declaration |
Role annotations
NominalR | nominal |
RepresentationalR | representational |
PhantomR | phantom |
InferR | _ |
Instances
Eq Role | |
Data Role | |
Defined in Language.Haskell.TH.Syntax gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Role -> c Role # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Role # dataTypeOf :: Role -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Role) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Role) # gmapT :: (forall b. Data b => b -> b) -> Role -> Role # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Role -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Role -> r # gmapQ :: (forall d. Data d => d -> u) -> Role -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Role -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Role -> m Role # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Role -> m Role # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Role -> m Role # | |
Ord Role | |
Show Role | |
Generic Role | |
Ppr Role | |
type Rep Role | |
Defined in Language.Haskell.TH.Syntax type Rep Role = D1 (MetaData "Role" "Language.Haskell.TH.Syntax" "template-haskell" False) ((C1 (MetaCons "NominalR" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "RepresentationalR" PrefixI False) (U1 :: Type -> Type)) :+: (C1 (MetaCons "PhantomR" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "InferR" PrefixI False) (U1 :: Type -> Type))) |
Instances
Eq AnnTarget | |
Data AnnTarget | |
Defined in Language.Haskell.TH.Syntax gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> AnnTarget -> c AnnTarget # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c AnnTarget # toConstr :: AnnTarget -> Constr # dataTypeOf :: AnnTarget -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c AnnTarget) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AnnTarget) # gmapT :: (forall b. Data b => b -> b) -> AnnTarget -> AnnTarget # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> AnnTarget -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> AnnTarget -> r # gmapQ :: (forall d. Data d => d -> u) -> AnnTarget -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> AnnTarget -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> AnnTarget -> m AnnTarget # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> AnnTarget -> m AnnTarget # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> AnnTarget -> m AnnTarget # | |
Ord AnnTarget | |
Defined in Language.Haskell.TH.Syntax | |
Show AnnTarget | |
Generic AnnTarget | |
type Rep AnnTarget | |
Defined in Language.Haskell.TH.Syntax type Rep AnnTarget = D1 (MetaData "AnnTarget" "Language.Haskell.TH.Syntax" "template-haskell" False) (C1 (MetaCons "ModuleAnnotation" PrefixI False) (U1 :: Type -> Type) :+: (C1 (MetaCons "TypeAnnotation" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Name)) :+: C1 (MetaCons "ValueAnnotation" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Name)))) |
The Desugar
class
class Desugar th ds | ds -> th where Source #
This class relates a TH type with its th-desugar type and allows
conversions back and forth. The functional dependency goes only one
way because Type
and Kind
are type synonyms, but they desugar
to different types.
Main desugaring functions
dsPatOverExp :: DsMonad q => Pat -> DExp -> q (DPat, DExp) Source #
Desugar a pattern, along with processing a (desugared) expression that is the entire scope of the variables bound in the pattern.
dsPatsOverExp :: DsMonad q => [Pat] -> DExp -> q ([DPat], DExp) Source #
Desugar multiple patterns. Like dsPatOverExp
.
dsPatX :: DsMonad q => Pat -> q (DPat, [(Name, DExp)]) Source #
Desugar a pattern, returning a list of (Name, DExp) pairs of extra variables that must be bound within the scope of the pattern
dsLetDecs :: DsMonad q => [Dec] -> q ([DLetDec], DExp -> DExp) Source #
Desugar Dec
s that can appear in a let
expression. See the
documentation for dsLetDec
for an explanation of what the return type
represents.
:: DsMonad q | |
=> [DTyVarBndr] | The universally quantified type variables (used if desugaring a non-GADT constructor). |
-> DType | The original data declaration's type (used if desugaring a non-GADT constructor). |
-> Con | |
-> q [DCon] |
Desugar a single Con
.
Because we always desugar Con
s to GADT syntax (see the documentation for
DCon
), it is not always possible to desugar with just a Con
alone.
For instance, we must desugar:
data Foo a = forall b. MkFoo b
To this:
data Foo a :: Type where MkFoo :: forall a b. b -> Foo a
If our only argument was forall b. MkFoo b
, it would be somewhat awkward
to figure out (1) what the set of universally quantified type variables
([a]
) was, and (2) what the return type (Foo a
) was. For this reason,
we require passing these as arguments. (If we desugar an actual GADT
constructor, these arguments are ignored.)
Secondary desugaring functions
type PatM q = WriterT [(Name, DExp)] q Source #
Desugaring a pattern also returns the list of variables bound in as-patterns and the values they should be bound to. This variables must be brought into scope in the "body" of the pattern.
dsDec :: DsMonad q => Dec -> q [DDec] Source #
Desugar a single Dec
, perhaps producing multiple DDec
s
dsDataDec :: DsMonad q => NewOrData -> Cxt -> Name -> [TyVarBndr] -> Maybe Kind -> [Con] -> [DerivingClause] -> q [DDec] Source #
dsDataInstDec :: DsMonad q => NewOrData -> Cxt -> Name -> Maybe [TyVarBndr] -> [TypeArg] -> Maybe Kind -> [Con] -> [DerivingClause] -> q [DDec] Source #
Desugar a DataInstD
or a NewtypeInstD
.
type DerivingClause = DerivClause Source #
A backwards-compatible type synonym for the thing representing a single
derived class in a deriving
clause. (This is a DerivClause
, Pred
, or
Name
depending on the GHC version.)
dsDerivClause :: DsMonad q => DerivingClause -> q DDerivClause Source #
Desugar a DerivingClause
.
dsLetDec :: DsMonad q => Dec -> q ([DLetDec], DExp -> DExp) Source #
Desugar a single Dec
that can appear in a let
expression.
This produces the following output:
- One or more
DLetDec
s (a singleDec
can produce multipleDLetDec
s in the event of a value declaration that binds multiple things by way of pattern matching. - A function of type
, which should be applied to the expression immediately following theDExp
->DExp
DLetDec
s. This function prepends binding forms for any implicit params that were bound in the argumentDec
. (If no implicit params are bound, this is simply theid
function.)
For instance, if the argument to dsLetDec
is the ?x = 42
part of this
expression:
let { ?x = 42 } in ?x
Then the output is:
let new_x_val = 42
\z ->
bindIP
@"x" new_x_val z
This way, the expression
let { new_x_val = 42 } in
can be
formed. The implicit param binders always come after all the other
bindIP
@"x" new_x_val (ip
@"x")DLetDec
s to support parallel assignment of implicit params.
:: DsMonad q | |
=> Name | Name of the scrutinee, which must be a bare var |
-> [Match] | Matches of the |
-> q [DMatch] |
Desugar a list of matches for a case
statement
:: DsMonad q | |
=> Body | body to desugar |
-> [Dec] | "where" declarations |
-> DExp | what to do if the guards don't match |
-> q DExp |
Desugar a Body
:: DsMonad q | |
=> [(Guard, Exp)] | Guarded expressions |
-> DExp | What to do if none of the guards match |
-> q DExp |
Desugar guarded expressions
Desugar clauses to a function definition
dsBangType :: DsMonad q => BangType -> q DBangType Source #
Desugar a BangType
(or a StrictType
, if you're old-fashioned)
dsVarBangType :: DsMonad q => VarBangType -> q DVarBangType Source #
Desugar a VarBangType
(or a VarStrictType
, if you're old-fashioned)
dsTypeFamilyHead :: DsMonad q => TypeFamilyHead -> q DTypeFamilyHead Source #
Desugar a TypeFamilyHead
dsFamilyResultSig :: DsMonad q => FamilyResultSig -> q DFamilyResultSig Source #
Desugar a FamilyResultSig
dsPatSynDir :: DsMonad q => Name -> PatSynDir -> q DPatSynDir Source #
Desugar a PatSynDir
. (Available only with GHC 8.2+)
Converting desugared AST back to TH AST
Expanding type synonyms
expandType :: DsMonad q => DType -> q DType Source #
Expands all type synonyms in a desugared type. Also expands open type family applications. (In GHCs before 7.10, this part does not work if there are any variables.) Attempts to expand closed type family applications, but aborts the moment it spots anything strange, like a nested type family application or type variable.
Reification
reifyWithWarning :: (Quasi q, MonadFail q) => Name -> q Info Source #
Reify a declaration, warning the user about splices if the reify fails. The warning says that reification can fail if you try to reify a type in the same splice as it is declared.
Local reification
template-haskell
reification functions like reify
and qReify
, as well as
th-desugar
's reifyWithWarning
, only look through declarations that either
(1) have already been typechecked in the current module, or (2) are in scope
because of imports. We refer to this as global reification. Sometimes,
however, you may wish to reify declarations that have been quoted but not
yet been typechecked, such as in the following example:
example :: IO ()
example = putStrLn
$(do decs <- [d| data Foo = MkFoo |]
info <- reify
(mkName "Foo")
stringE $ pprint info)
Because Foo
only exists in a TH quote, it is not available globally. As a
result, the call to
will fail.reify
(mkName "Foo")
To make this sort of example possible, th-desugar
extends global reification
with local reification. A function that performs local reification (such
as dsReify
, reifyWithLocals
, or similar functions that have a DsMonad
context) looks through both typechecked (or imported) declarations and quoted
declarations that are currently in scope. One can add quoted declarations in
the current scope by using the withLocalDeclarations
function. Here is an
example of how to repair the example above using withLocalDeclarations
:
example2 :: IO () example2 = putStrLn $(do decs <- [d| data Foo = MkFoo |] info <-withLocalDeclarations
decs $reifyWithLocals
(mkName "Foo") stringE $ pprint info)
Note that withLocalDeclarations
should only be used to add quoted
declarations with names that are not duplicates of existing global or local
declarations. Adding duplicate declarations through withLocalDeclarations
is undefined behavior and should be avoided. This is unlikely to happen if
you are only using withLocalDeclarations
in conjunction with TH quotes,
however. For instance, this is not an example of duplicate declarations:
data T = MkT1
$(do decs <- [d| data T = MkT2 |]
info <- withLocalDeclarations
decs ...
...)
The quoted data T = MkT2
does not conflict with the top-level data T = Mk1
since declaring a data type within TH quotes gives it a fresh, unique name that
distinguishes it from any other data types already in scope.
withLocalDeclarations :: DsMonad q => [Dec] -> DsM q a -> q a Source #
Add a list of declarations to be considered when reifying local declarations.
dsReify :: DsMonad q => Name -> q (Maybe DInfo) Source #
Like reify
, but safer and desugared. Uses local declarations where
available.
dsReifyType :: DsMonad q => Name -> q (Maybe DType) Source #
Like reifyType
, but safer and desugared. Uses local declarations where
available.
reifyWithLocals_maybe :: DsMonad q => Name -> q (Maybe Info) Source #
Like reify
from Template Haskell, but looks also in any not-yet-typechecked
declarations. To establish this list of not-yet-typechecked declarations,
use withLocalDeclarations
. Returns Nothing
if reification fails.
Note that no inferred type information is available from local declarations;
bottoms may be used if necessary.
reifyWithLocals :: DsMonad q => Name -> q Info Source #
Like reifyWithLocals_maybe
, but throws an exception upon failure,
warning the user about separating splices.
reifyFixityWithLocals :: DsMonad q => Name -> q (Maybe Fixity) Source #
Like reifyWithLocals_maybe
, but for fixities. Note that a return value
of Nothing
might mean that the name is not in scope, or it might mean
that the name has no assigned fixity. (Use reifyWithLocals_maybe
if
you really need to tell the difference.)
reifyTypeWithLocals_maybe :: DsMonad q => Name -> q (Maybe Type) Source #
Like reifyWithLocals_maybe
but for types and kinds. Note that a return
value of Nothing
might mean that the name is not in scope, or it might
mean that the full type of the name cannot be determined. (Use
reifyWithLocals_maybe
if you really need to tell the difference.)
reifyTypeWithLocals :: DsMonad q => Name -> q Type Source #
Like reifyTypeWithLocals_maybe
, but throws an exception upon failure,
warning the user about separating splices.
lookupValueNameWithLocals :: DsMonad q => String -> q (Maybe Name) Source #
Like lookupValueName
from Template Haskell, but looks also in Names
of
not-yet-typechecked declarations. To establish this list of not-yet-typechecked
declarations, use withLocalDeclarations
. Returns Nothing
if no value
with the same name can be found.
lookupTypeNameWithLocals :: DsMonad q => String -> q (Maybe Name) Source #
Like lookupTypeName
from Template Haskell, but looks also in Names
of
not-yet-typechecked declarations. To establish this list of not-yet-typechecked
declarations, use withLocalDeclarations
. Returns Nothing
if no type
with the same name can be found.
mkDataNameWithLocals :: DsMonad q => String -> q Name Source #
Like TH's lookupValueName
, but if this name is not bound, then we assume
it is declared in the current module.
Unlike mkDataName
, this also consults the local declarations in scope when
determining if the name is currently bound.
mkTypeNameWithLocals :: DsMonad q => String -> q Name Source #
Like TH's lookupTypeName
, but if this name is not bound, then we assume
it is declared in the current module.
Unlike mkTypeName
, this also consults the local declarations in scope when
determining if the name is currently bound.
reifyNameSpace :: DsMonad q => Name -> q (Maybe NameSpace) Source #
Determines a Name
's NameSpace
. If the NameSpace
is attached to
the Name
itself (i.e., it is unambiguous), then that NameSpace
is
immediately returned. Otherwise, reification is used to lookup up the
NameSpace
(consulting local declarations if necessary).
Note that if a Name
lives in two different NameSpaces
(which can
genuinely happen--for instance,
, where mkName
"=="==
is both
a function and a type family), then this function will simply return
whichever NameSpace
is discovered first via reification. If you wish
to find a Name
in a particular NameSpace
, use the
lookupValueNameWithLocals
or lookupTypeNameWithLocals
functions.
class (Quasi m, MonadFail m) => DsMonad m where Source #
A DsMonad
stores some list of declarations that should be considered
in scope. DsM
is the prototypical inhabitant of DsMonad
.
localDeclarations :: m [Dec] Source #
Produce a list of local declarations.
Instances
DsMonad IO Source # | |
Defined in Language.Haskell.TH.Desugar.Reify localDeclarations :: IO [Dec] Source # | |
DsMonad Q Source # | |
Defined in Language.Haskell.TH.Desugar.Reify localDeclarations :: Q [Dec] Source # | |
(Quasi q, MonadFail q) => DsMonad (DsM q) Source # | |
Defined in Language.Haskell.TH.Desugar.Reify localDeclarations :: DsM q [Dec] Source # | |
DsMonad m => DsMonad (StateT s m) Source # | |
Defined in Language.Haskell.TH.Desugar.Reify localDeclarations :: StateT s m [Dec] Source # | |
(DsMonad m, Monoid w) => DsMonad (WriterT w m) Source # | |
Defined in Language.Haskell.TH.Desugar.Reify localDeclarations :: WriterT w m [Dec] Source # | |
DsMonad m => DsMonad (ReaderT r m) Source # | |
Defined in Language.Haskell.TH.Desugar.Reify localDeclarations :: ReaderT r m [Dec] Source # | |
(DsMonad m, Monoid w) => DsMonad (RWST r w s m) Source # | |
Defined in Language.Haskell.TH.Desugar.Reify localDeclarations :: RWST r w s m [Dec] Source # |
A convenient implementation of the DsMonad
class. Use by calling
withLocalDeclarations
.
Instances
Nested pattern flattening
scExp :: DsMonad q => DExp -> q DExp Source #
Remove all nested pattern-matches within this expression. This also
removes all DTildePa
s and DBangPa
s. After this is run, every pattern
is guaranteed to be either a DConPa
with bare variables as arguments,
a DLitPa
, or a DWildPa
.
Capture-avoiding substitution and utilities
Free variable calculation
extractBoundNamesDPat :: DPat -> OSet Name Source #
Extract the term variables bound by a DPat
.
This does not extract any type variables bound by pattern signatures.
Utility functions
removeWilds :: DsMonad q => DPat -> q DPat Source #
Remove all wildcards from a pattern, replacing any wildcard with a fresh variable
:: DsMonad q | |
=> String | Print this out on failure |
-> Name | Name of the datatype ( |
-> q ([TyVarBndr], [Con]) |
Extract the TyVarBndr
s and constructors given the Name
of a type
dataConNameToDataName :: DsMonad q => Name -> q Name Source #
From the name of a data constructor, retrive the datatype definition it is a part of.
dataConNameToCon :: DsMonad q => Name -> q Con Source #
From the name of a data constructor, retrieve its definition as a Con
nameOccursIn :: Data a => Name -> a -> Bool Source #
Check if a name occurs anywhere within a TH tree.
allNamesIn :: Data a => a -> [Name] Source #
Extract all Names mentioned in a TH tree.
flattenDValD :: Quasi q => DLetDec -> q [DLetDec] Source #
If the declaration passed in is a DValD
, creates new, equivalent
declarations such that the DPat
in all DValD
s is just a plain
DVarPa
. Other declarations are passed through unchanged.
Note that the declarations that come out of this function are rather
less efficient than those that come in: they have many more pattern
matches.
Produces DLetDec
s representing the record selector functions from
the provided DCon
s.
Note that if the same record selector appears in multiple constructors,
getRecordSelectors
will return only one binding for that selector.
For example, if you had:
data X = X1 {y :: Symbol} | X2 {y :: Symbol}
Then calling getRecordSelectors
on [X1, X2]
will return:
[ DSigD y (DAppT (DAppT DArrowT (DConT X)) (DConT Symbol)) , DFunD y [ DClause [DConP X1 [DVarP field]] (DVarE field) , DClause [DConP X2 [DVarP field]] (DVarE field) ] ]
instead of returning one binding for X1
and another binding for X2
.
getRecordSelectors
attempts to filter out "naughty" record selectors
whose types mention existentially quantified type variables. But see the
documentation for conExistentialTvbs
for limitations to this approach.
mkTypeName :: Quasi q => String -> q Name Source #
Like TH's lookupTypeName
, but if this name is not bound, then we assume
it is declared in the current module.
mkDataName :: Quasi q => String -> q Name Source #
Like TH's lookupDataName
, but if this name is not bound, then we assume
it is declared in the current module.
newUniqueName :: Quasi q => String -> q Name Source #
Like newName, but even more unique (unique across different splices),
and with unique nameBase
s. Precondition: the string is a valid Haskell
alphanumeric identifier (could be upper- or lower-case).
mkTupleDExp :: [DExp] -> DExp Source #
mkTupleDPat :: [DPat] -> DPat Source #
maybeDCaseE :: String -> DExp -> [DMatch] -> DExp Source #
If matches is non-empty, make a case statement; otherwise make an error statement
unboxedTupleNameDegree_maybe :: Name -> Maybe Int Source #
Extract the degree of an unboxed tuple name
strictToBang :: Bang -> Bang Source #
isTypeKindName :: Name -> Bool Source #
typeKindName :: Name Source #
bindIP :: forall name a r. a -> (IP name a => r) -> r Source #
Get an implicit param constraint (IP name a
, which is the desugared
form of (?name :: a)
) from an explicit value.
This function is only available with GHC 8.0 or later.
:: DsMonad q | |
=> DType | The type of the original data declaration |
-> DCon | |
-> q [DTyVarBndr] |
Returns all of a constructor's existentially quantified type variable binders.
Detecting the presence of existentially quantified type variables in the context of Template Haskell is quite involved. Here is an example that we will use to explain how this works:
data family Foo a b data instance Foo (Maybe a) b where MkFoo :: forall x y z. x -> y -> z -> Foo (Maybe x) [z]
In MkFoo
, x
is universally quantified, whereas y
and z
are
existentially quantified. Note that MkFoo
desugars (in Core) to
something like this:
data instance Foo (Maybe a) b where MkFoo :: forall a b y z. (b ~ [z]). a -> y -> z -> Foo (Maybe a) b
Here, we can see that a
appears in the desugared return type (it is a
simple alpha-renaming of x
), so it is universally quantified. On the other
hand, neither y
nor z
appear in the desugared return type, so they are
existentially quantified.
This analysis would not have been possible without knowing what the original
data declaration's type was (in this case, Foo (Maybe a) b
), which is why
we require it as an argument. Our algorithm for detecting existentially
quantified variables is not too different from what was described above:
we match the constructor's return type with the original data type, forming
a substitution, and check which quantified variables are not part of the
domain of the substitution.
Be warned: this may overestimate which variables are existentially quantified when kind variables are involved. For instance, consider this example:
data S k (a :: k) data T a where MkT :: forall k (a :: k). { foo :: Proxy (a :: k), bar :: S k a } -> T a
Here, the kind variable k
does not appear syntactically in the return type
T a
, so conExistentialTvbs
would mistakenly flag k
as existential.
There are various tricks we could employ to improve this, but ultimately,
making this behave correctly with respect to PolyKinds
100% of the time
would amount to performing kind inference in Template Haskell, which is
quite difficult. For the sake of simplicity, we have decided to stick with
a dumb-but-predictable syntactic check.
mkExtraDKindBinders :: forall q. DsMonad q => DKind -> q [DTyVarBndr] Source #
Create new kind variable binder names corresponding to the return kind of a data type. This is useful when you have a data type like:
data Foo :: forall k. k -> Type -> Type where ...
But you want to be able to refer to the type Foo a b
.
mkExtraDKindBinders
will take the kind forall k. k -> Type -> Type
,
discover that is has two visible argument kinds, and return as a result
two new kind variable binders [a :: k, b :: Type]
, where a
and b
are fresh type variable names.
This expands kind synonyms if necessary.
dTyVarBndrToDType :: DTyVarBndr -> DType Source #
Convert a DTyVarBndr
into a DType
toposortTyVarsOf :: [DType] -> [DTyVarBndr] Source #
Take a list of DType
s, find their free variables, and sort them in
reverse topological order to ensure that they are well scoped. In other
words, the free variables are ordered such that:
- Whenever an explicit kind signature of the form
(A :: K)
is encountered, the free variables ofK
will always appear to the left of the free variables ofA
in the returned result. - 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
.
FunArgs
and VisFunArg
The list of arguments in a function Type
.
FANil | No more arguments. |
FAForalls ForallVisFlag [TyVarBndr] FunArgs | A series of |
FACxt Cxt FunArgs | A series of constraint arguments followed by |
FAAnon Type FunArgs | An anonymous argument followed by an arrow. For example, the |
Instances
Eq FunArgs Source # | |
Data FunArgs Source # | |
Defined in Language.Haskell.TH.Desugar.Util gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> FunArgs -> c FunArgs # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c FunArgs # toConstr :: FunArgs -> Constr # dataTypeOf :: FunArgs -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c FunArgs) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FunArgs) # gmapT :: (forall b. Data b => b -> b) -> FunArgs -> FunArgs # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> FunArgs -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> FunArgs -> r # gmapQ :: (forall d. Data d => d -> u) -> FunArgs -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> FunArgs -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> FunArgs -> m FunArgs # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> FunArgs -> m FunArgs # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> FunArgs -> m FunArgs # | |
Show FunArgs Source # | |
Lift FunArgs Source # | |
A visible function argument type (i.e., one that must be supplied
explicitly in the source code). This is in contrast to invisible
arguments (e.g., the c
in c => r
), which are instantiated without
the need for explicit user input.
VisFADep TyVarBndr | A visible |
VisFAAnon Type | An anonymous argument followed by an arrow (e.g., |
Instances
Eq VisFunArg Source # | |
Data VisFunArg Source # | |
Defined in Language.Haskell.TH.Desugar.Util gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> VisFunArg -> c VisFunArg # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c VisFunArg # toConstr :: VisFunArg -> Constr # dataTypeOf :: VisFunArg -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c VisFunArg) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c VisFunArg) # gmapT :: (forall b. Data b => b -> b) -> VisFunArg -> VisFunArg # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> VisFunArg -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> VisFunArg -> r # gmapQ :: (forall d. Data d => d -> u) -> VisFunArg -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> VisFunArg -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg # | |
Show VisFunArg Source # | |
Lift VisFunArg Source # | |
filterVisFunArgs :: FunArgs -> [VisFunArg] Source #
Filter the visible function arguments from a list of FunArgs
.
ravelType :: FunArgs -> Type -> Type Source #
Reconstruct an arrow Type
from its argument and result types.
DFunArgs
and DVisFunArg
The list of arguments in a function DType
.
DFANil | No more arguments. |
DFAForalls ForallVisFlag [DTyVarBndr] DFunArgs | A series of |
DFACxt DCxt DFunArgs | A series of constraint arguments followed by |
DFAAnon DType DFunArgs | An anonymous argument followed by an arrow. For example, the |
Instances
data DVisFunArg Source #
A visible function argument type (i.e., one that must be supplied
explicitly in the source code). This is in contrast to invisible
arguments (e.g., the c
in c => r
), which are instantiated without
the need for explicit user input.
DVisFADep DTyVarBndr | A visible |
DVisFAAnon DType | An anonymous argument followed by an arrow (e.g., |
Instances
filterDVisFunArgs :: DFunArgs -> [DVisFunArg] Source #
Filter the visible function arguments from a list of DFunArgs
.
ravelDType :: DFunArgs -> DType -> DType Source #
Reconstruct an arrow DType
from its argument and result types.
TypeArg
An argument to a type, either a normal type (TANormal
) or a visible
kind application (TyArg
).
TypeArg
is useful when decomposing an application of a Type
to its
arguments (e.g., in unfoldType
).
Instances
Eq TypeArg Source # | |
Data TypeArg Source # | |
Defined in Language.Haskell.TH.Desugar.Util gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> TypeArg -> c TypeArg # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c TypeArg # toConstr :: TypeArg -> Constr # dataTypeOf :: TypeArg -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c TypeArg) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeArg) # gmapT :: (forall b. Data b => b -> b) -> TypeArg -> TypeArg # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TypeArg -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TypeArg -> r # gmapQ :: (forall d. Data d => d -> u) -> TypeArg -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> TypeArg -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> TypeArg -> m TypeArg # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> TypeArg -> m TypeArg # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> TypeArg -> m TypeArg # | |
Show TypeArg Source # | |
Lift TypeArg Source # | |
Desugar TypeArg DTypeArg Source # | |
filterTANormals :: [TypeArg] -> [Type] Source #
Filter the normal type arguments from a list of TypeArg
s.
DTypeArg
An argument to a type, either a normal type (DTANormal
) or a visible
kind application (DTyArg
).
DTypeArg
does not appear directly in the th-desugar
AST, but it is
useful when decomposing an application of a DType
to its arguments.
Instances
Eq DTypeArg Source # | |
Data DTypeArg Source # | |
Defined in Language.Haskell.TH.Desugar.Core gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> DTypeArg -> c DTypeArg # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c DTypeArg # toConstr :: DTypeArg -> Constr # dataTypeOf :: DTypeArg -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c DTypeArg) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DTypeArg) # gmapT :: (forall b. Data b => b -> b) -> DTypeArg -> DTypeArg # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> DTypeArg -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> DTypeArg -> r # gmapQ :: (forall d. Data d => d -> u) -> DTypeArg -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> DTypeArg -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> DTypeArg -> m DTypeArg # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> DTypeArg -> m DTypeArg # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> DTypeArg -> m DTypeArg # | |
Show DTypeArg Source # | |
Generic DTypeArg Source # | |
Lift DTypeArg Source # | |
Desugar TypeArg DTypeArg Source # | |
type Rep DTypeArg Source # | |
Defined in Language.Haskell.TH.Desugar.Core type Rep DTypeArg = D1 (MetaData "DTypeArg" "Language.Haskell.TH.Desugar.Core" "th-desugar-1.11-6CeS211oN4bGxRJRLZG2AP" False) (C1 (MetaCons "DTANormal" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 DType)) :+: C1 (MetaCons "DTyArg" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 DKind))) |
filterDTANormals :: [DTypeArg] -> [DType] Source #
Filter the normal type arguments from a list of DTypeArg
s.