-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Functions to desugar Template Haskell
--   
--   This package provides the Language.Haskell.TH.Desugar module, which
--   desugars Template Haskell's rich encoding of Haskell syntax into a
--   simpler encoding. This desugaring discards surface syntax information
--   (such as the use of infix operators) but retains the original meaning
--   of the TH code. The intended use of this package is as a preprocessor
--   for more advanced code manipulation tools. Note that the input to any
--   of the ds... functions should be produced from a TH quote, using the
--   syntax [| ... |]. If the input to these functions is a hand-coded TH
--   syntax tree, the results may be unpredictable. In particular, it is
--   likely that promoted datatypes will not work as expected.
@package th-desugar
@version 1.17

-- | An OMap behaves much like a Map, with all the same
--   asymptotics, but also remembers the order that keys were inserted.
--   
--   This module offers a simplified version of the Data.Map.Ordered
--   API that assumes left-biased indices everywhere and uses a different
--   Semigroup instance (the one in this module uses
--   (<>) = union) and Monoid instance
--   (the one in this module uses mappend = union).
module Language.Haskell.TH.Desugar.OMap

-- | An ordered map whose insertPre, insertPost,
--   intersection, intersectionWithKey, union, and
--   unionWithKey operations are biased towards leftmost indices
--   when when breaking ties between keys.
newtype OMap k v
OMap :: Bias L (OMap k v) -> OMap k v
empty :: OMap k v
singleton :: k -> v -> OMap k v

-- | The value's index will be lower than the indices of the values in the
--   OSet.
insertPre :: Ord k => k -> v -> OMap k v -> OMap k v

-- | The value's index will be higher than the indices of the values in the
--   OSet.
insertPost :: Ord k => OMap k v -> k -> v -> OMap k v
union :: Ord k => OMap k v -> OMap k v -> OMap k v
unionWithKey :: Ord k => (k -> v -> v -> v) -> OMap k v -> OMap k v -> OMap k v
delete :: Ord k => k -> OMap k v -> OMap k v
filterWithKey :: Ord k => (k -> v -> Bool) -> OMap k v -> OMap k v
(\\) :: Ord k => OMap k v -> OMap k v' -> OMap k v
intersection :: Ord k => OMap k v -> OMap k v' -> OMap k v
intersectionWithKey :: Ord k => (k -> v -> v' -> v'') -> OMap k v -> OMap k v' -> OMap k v''
null :: OMap k v -> Bool
size :: OMap k v -> Int
member :: Ord k => k -> OMap k v -> Bool
notMember :: Ord k => k -> OMap k v -> Bool
lookup :: Ord k => k -> OMap k v -> Maybe v

-- | A 0-based index, much like the indices used by lists' !!
--   operation. All indices are with respect to insertion order.
type Index = Int
lookupIndex :: Ord k => k -> OMap k v -> Maybe Index
lookupAt :: Index -> OMap k v -> Maybe (k, v)
fromList :: Ord k => [(k, v)] -> OMap k v
assocs :: OMap k v -> [(k, v)]
toAscList :: OMap k v -> [(k, v)]
toMap :: OMap k v -> Map k v
instance (GHC.Internal.Data.Data.Data k, GHC.Internal.Data.Data.Data v, GHC.Classes.Ord k) => GHC.Internal.Data.Data.Data (Language.Haskell.TH.Desugar.OMap.OMap k v)
instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Language.Haskell.TH.Desugar.OMap.OMap k v)
instance GHC.Internal.Data.Foldable.Foldable (Language.Haskell.TH.Desugar.OMap.OMap k)
instance GHC.Internal.Base.Functor (Language.Haskell.TH.Desugar.OMap.OMap k)
instance GHC.Classes.Ord k => GHC.Internal.Base.Monoid (Language.Haskell.TH.Desugar.OMap.OMap k v)
instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (Language.Haskell.TH.Desugar.OMap.OMap k v)
instance (GHC.Classes.Ord k, GHC.Internal.Read.Read k, GHC.Internal.Read.Read v) => GHC.Internal.Read.Read (Language.Haskell.TH.Desugar.OMap.OMap k v)
instance GHC.Classes.Ord k => GHC.Internal.Base.Semigroup (Language.Haskell.TH.Desugar.OMap.OMap k v)
instance (GHC.Internal.Show.Show k, GHC.Internal.Show.Show v) => GHC.Internal.Show.Show (Language.Haskell.TH.Desugar.OMap.OMap k v)
instance GHC.Classes.Ord k => GHC.Internal.Data.Traversable.Traversable (Language.Haskell.TH.Desugar.OMap.OMap k)

-- | An OMap behaves much like a Map, with all the same
--   asymptotics, but also remembers the order that keys were inserted.
--   
--   This module offers a simplified version of the
--   Data.Map.Ordered.Strict API that assumes left-biased indices
--   everywhere and uses a different Semigroup instance (the one in
--   this module uses (<>) = union) and
--   Monoid instance (the one in this module uses mappend
--   = union).
module Language.Haskell.TH.Desugar.OMap.Strict

-- | An ordered map whose insertPre, insertPost,
--   intersection, intersectionWithKey, union, and
--   unionWithKey operations are biased towards leftmost indices
--   when when breaking ties between keys.
newtype OMap k v
OMap :: Bias L (OMap k v) -> OMap k v
empty :: OMap k v
singleton :: k -> v -> OMap k v

-- | The value's index will be lower than the indices of the values in the
--   OSet.
insertPre :: Ord k => k -> v -> OMap k v -> OMap k v

-- | The value's index will be higher than the indices of the values in the
--   OSet.
insertPost :: Ord k => OMap k v -> k -> v -> OMap k v
union :: Ord k => OMap k v -> OMap k v -> OMap k v
unionWithKey :: Ord k => (k -> v -> v -> v) -> OMap k v -> OMap k v -> OMap k v
delete :: Ord k => k -> OMap k v -> OMap k v
filterWithKey :: Ord k => (k -> v -> Bool) -> OMap k v -> OMap k v
(\\) :: Ord k => OMap k v -> OMap k v' -> OMap k v
intersection :: Ord k => OMap k v -> OMap k v' -> OMap k v
intersectionWithKey :: Ord k => (k -> v -> v' -> v'') -> OMap k v -> OMap k v' -> OMap k v''
null :: OMap k v -> Bool
size :: OMap k v -> Int
member :: Ord k => k -> OMap k v -> Bool
notMember :: Ord k => k -> OMap k v -> Bool
lookup :: Ord k => k -> OMap k v -> Maybe v

-- | A 0-based index, much like the indices used by lists' !!
--   operation. All indices are with respect to insertion order.
type Index = Int
lookupIndex :: Ord k => k -> OMap k v -> Maybe Index
lookupAt :: Index -> OMap k v -> Maybe (k, v)
fromList :: Ord k => [(k, v)] -> OMap k v
assocs :: OMap k v -> [(k, v)]
toAscList :: OMap k v -> [(k, v)]
toMap :: OMap k v -> Map k v

-- | An OSet behaves much like a Set, with all the same
--   asymptotics, but also remembers the order that values were inserted.
--   
--   This module offers a simplified version of the Data.Set.Ordered
--   API that assumes left-biased indices everywhere.
module Language.Haskell.TH.Desugar.OSet

-- | An ordered set whose insertPre, insertPost,
--   intersection, and union operations are biased towards
--   leftmost indices when when breaking ties between keys.
data OSet a
empty :: OSet a
singleton :: a -> OSet a

-- | The element's index will be lower than the indices of the elements in
--   the OSet.
insertPre :: Ord a => a -> OSet a -> OSet a

-- | The element's index will be higher than the indices of the elements in
--   the OSet.
insertPost :: Ord a => OSet a -> a -> OSet a
union :: Ord a => OSet a -> OSet a -> OSet a
null :: OSet a -> Bool
size :: OSet a -> Int
member :: Ord a => a -> OSet a -> Bool
notMember :: Ord a => a -> OSet a -> Bool
delete :: Ord a => a -> OSet a -> OSet a
filter :: Ord a => (a -> Bool) -> OSet a -> OSet a
(\\) :: Ord a => OSet a -> OSet a -> OSet a
intersection :: Ord a => OSet a -> OSet a -> OSet a

-- | A 0-based index, much like the indices used by lists' !!
--   operation. All indices are with respect to insertion order.
type Index = Int
lookupIndex :: Ord a => a -> OSet a -> Maybe Index
lookupAt :: Index -> OSet a -> Maybe a
fromList :: Ord a => [a] -> OSet a
toAscList :: OSet a -> [a]
toSet :: OSet a -> Set a
instance (GHC.Internal.Data.Data.Data a, GHC.Classes.Ord a) => GHC.Internal.Data.Data.Data (Language.Haskell.TH.Desugar.OSet.OSet a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.Haskell.TH.Desugar.OSet.OSet a)
instance GHC.Internal.Data.Foldable.Foldable Language.Haskell.TH.Desugar.OSet.OSet
instance GHC.Classes.Ord a => GHC.Internal.Base.Monoid (Language.Haskell.TH.Desugar.OSet.OSet a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Language.Haskell.TH.Desugar.OSet.OSet a)
instance (GHC.Classes.Ord a, GHC.Internal.Read.Read a) => GHC.Internal.Read.Read (Language.Haskell.TH.Desugar.OSet.OSet a)
instance GHC.Classes.Ord a => GHC.Internal.Base.Semigroup (Language.Haskell.TH.Desugar.OSet.OSet a)
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Language.Haskell.TH.Desugar.OSet.OSet a)

-- | Capture-avoiding substitutions on DTypes
module Language.Haskell.TH.Desugar.Subst

-- | A substitution is just a map from names to types
type DSubst = Map Name DType

-- | Capture-avoiding substitution on types
substTy :: Quasi q => DSubst -> DType -> q DType
substForallTelescope :: Quasi q => DSubst -> DForallTelescope -> q (DSubst, DForallTelescope)
substTyVarBndrs :: Quasi q => DSubst -> [DTyVarBndr flag] -> q (DSubst, [DTyVarBndr flag])

-- | Computes the union of two substitutions. Fails if both subsitutions
--   map the same variable to different types.
unionSubsts :: DSubst -> DSubst -> Maybe DSubst
unionMaybeSubsts :: [Maybe DSubst] -> Maybe DSubst

-- | Ignore kind annotations in matchTy?
data IgnoreKinds
YesIgnore :: IgnoreKinds
NoIgnore :: IgnoreKinds

-- | matchTy ign tmpl targ matches a type template tmpl
--   against a type target targ. This returns a Map from names of
--   type variables in the type template to types if the types indeed match
--   up, or Nothing otherwise. In the Just case, it is
--   guaranteed that every type variable mentioned in the template is
--   mapped by the returned substitution.
--   
--   The first argument ign tells matchTy whether to
--   ignore kind signatures in the template. A kind signature in the
--   template might mean that a type variable has a more restrictive kind
--   than otherwise possible, and that mapping that type variable to a type
--   of a different kind could be disastrous. So, if we don't ignore kind
--   signatures, this function returns Nothing if the template has
--   a signature anywhere. If we do ignore kind signatures, it's possible
--   the returned map will be ill-kinded. Use at your own risk.
matchTy :: IgnoreKinds -> DType -> DType -> Maybe DSubst

-- | The functions in this module convert desugared Template Haskell back
--   into proper Template Haskell.
module Language.Haskell.TH.Desugar.Sweeten
expToTH :: DExp -> Exp
matchToTH :: DMatch -> Match
patToTH :: DPat -> Pat
decsToTH :: [DDec] -> [Dec]

-- | This returns a list of Decs because GHC 7.6.3 does not have a
--   one-to-one mapping between DDec and Dec.
decToTH :: DDec -> Dec

-- | Sweeten a DLetDec.
letDecToTH :: DLetDec -> Dec
typeToTH :: DType -> Type
conToTH :: DCon -> Con
foreignToTH :: DForeign -> Foreign
pragmaToTH :: DPragma -> Pragma
ruleBndrToTH :: DRuleBndr -> RuleBndr
clauseToTH :: DClause -> Clause
tvbToTH :: DTyVarBndr flag -> TyVarBndr_ flag
cxtToTH :: DCxt -> Cxt
predToTH :: DPred -> Pred
derivClauseToTH :: DDerivClause -> [DerivClause]
patSynDirToTH :: DPatSynDir -> PatSynDir
typeArgToTH :: DTypeArg -> TypeArg

-- | Expands type synonyms and type families in desugared types. See also
--   the package th-expand-syns for doing this to non-desugared types.
module Language.Haskell.TH.Desugar.Expand

-- | Expand all type synonyms and type families in the desugared abstract
--   syntax tree provided, where type family simplification is on a "best
--   effort" basis. Normally, the first parameter should have a type like
--   DExp or DLetDec.
expand :: (DsMonad q, Data a) => a -> q a

-- | 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.
expandType :: DsMonad q => DType -> q DType

-- | Expand all type synonyms and type families in the desugared abstract
--   syntax tree provided, where type family simplification is on a "better
--   than best effort" basis. This means that it will try so hard that it
--   will sometimes do the wrong thing. Specifically, any kind parameters
--   to type families are ignored. So, if we have
--   
--   
--   type family F (x :: k) where
--     F (a :: *) = Int
--   
--   
--   expandUnsoundly will expand F 'True to Int,
--   ignoring that the expansion should only work for type of kind
--   *.
--   
--   This function is useful because plain old expand will simply
--   fail to expand type families that make use of kinds. Sometimes, the
--   kinds are benign and we want to expand anyway. Use this function in
--   that case.
expandUnsoundly :: (DsMonad q, Data a) => a -> q a

-- | Desugars full Template Haskell syntax into a smaller core syntax for
--   further processing.
module Language.Haskell.TH.Desugar

-- | Corresponds to TH's Exp type. Note that DLamE takes
--   names, not patterns.
data DExp
DVarE :: Name -> DExp
DConE :: Name -> DExp
DLitE :: Lit -> DExp
DAppE :: DExp -> DExp -> DExp
DAppTypeE :: DExp -> DType -> DExp
DLamE :: [Name] -> DExp -> DExp
DCaseE :: DExp -> [DMatch] -> DExp
DLetE :: [DLetDec] -> DExp -> DExp
DSigE :: DExp -> DType -> DExp
DStaticE :: DExp -> DExp
DTypedBracketE :: DExp -> DExp
DTypedSpliceE :: DExp -> DExp
DTypeE :: DType -> DExp

-- | Declarations as used in a let statement.
data DLetDec
DFunD :: Name -> [DClause] -> DLetDec
DValD :: DPat -> DExp -> DLetDec
DSigD :: Name -> DType -> DLetDec
DInfixD :: Fixity -> NamespaceSpecifier -> Name -> DLetDec
DPragmaD :: DPragma -> DLetDec

-- | A way to specify a namespace to look in when GHC needs to find a
--   name's source
data NamespaceSpecifier

-- | Name may be everything; If there are two names in different
--   namespaces, then consider both
NoNamespaceSpecifier :: NamespaceSpecifier

-- | Name should be a type-level entity, such as a data type, type alias,
--   type family, type class, or type variable
TypeNamespaceSpecifier :: NamespaceSpecifier

-- | Name should be a term-level entity, such as a function, data
--   constructor, or pattern synonym
DataNamespaceSpecifier :: NamespaceSpecifier

-- | Corresponds to TH's Pat type.
data DPat
DLitP :: Lit -> DPat
DVarP :: Name -> DPat
DConP :: Name -> [DType] -> [DPat] -> DPat
DTildeP :: DPat -> DPat
DBangP :: DPat -> DPat
DSigP :: DPat -> DType -> DPat
DWildP :: DPat

-- | Note that th-desugar only has partial support for desugaring
--   embedded type patterns. In particular, th-desugar supports
--   desugaring embedded type patterns in function clauses, but not in
--   lambda expressions, \case expressions, or \cases
--   expressions. See the "Known limitations" section of the
--   th-desugar README for more details.
DTypeP :: DType -> DPat

-- | Note that th-desugar only has partial support for desugaring
--   invisible type patterns. In particular, th-desugar supports
--   desugaring invisible type patterns in function clauses, but not in
--   lambda expressions or \cases expressions. See the "Known
--   limitations" section of the th-desugar README for
--   more details.
DInvisP :: DType -> DPat

-- | Corresponds to TH's Type type, used to represent types and
--   kinds.
data DType
DForallT :: DForallTelescope -> DType -> DType
DConstrainedT :: DCxt -> DType -> DType
DAppT :: DType -> DType -> DType
DAppKindT :: DType -> DKind -> DType
DSigT :: DType -> DKind -> DType
DVarT :: Name -> DType
DConT :: Name -> DType
DArrowT :: DType
DLitT :: TyLit -> DType
DWildCardT :: DType

-- | The type variable binders in a forall.
data DForallTelescope

-- | A visible forall (e.g., forall a -> {...}). These
--   do not have any notion of specificity, so we use () as a
--   placeholder value in the DTyVarBndrs.
DForallVis :: [DTyVarBndrUnit] -> DForallTelescope

-- | An invisible forall (e.g., forall a {b} c ->
--   {...}), where each binder has a Specificity.
DForallInvis :: [DTyVarBndrSpec] -> DForallTelescope

-- | Kinds are types. Corresponds to TH's Kind
type DKind = DType

-- | Corresponds to TH's Cxt
type DCxt = [DPred]

-- | Predicates are types. Corresponds to TH's Pred
type DPred = DType

-- | Corresponds to TH's TyVarBndr
data DTyVarBndr flag
DPlainTV :: Name -> flag -> DTyVarBndr flag
DKindedTV :: Name -> flag -> DKind -> DTyVarBndr flag

-- | Corresponds to TH's TyVarBndrSpec
type DTyVarBndrSpec = DTyVarBndr Specificity

-- | Corresponds to TH's TyVarBndrUnit
type DTyVarBndrUnit = DTyVarBndr ()
data Specificity

-- | 
--   a
--   
SpecifiedSpec :: Specificity

-- | 
--   {a}
--   
InferredSpec :: Specificity

-- | Corresponds to TH's TyVarBndrVis
type DTyVarBndrVis = DTyVarBndr BndrVis
data BndrVis

-- | 
--   a
--   
BndrReq :: BndrVis

-- | 
--   @a
--   
BndrInvis :: BndrVis

-- | Corresponds to TH's Match type.
data DMatch
DMatch :: DPat -> DExp -> DMatch

-- | Corresponds to TH's Clause type.
data DClause
DClause :: [DPat] -> DExp -> DClause

-- | Corresponds to TH's Dec type.
data DDec
DLetDec :: DLetDec -> DDec

-- | An ordinary (i.e., non-data family) data type declaration. Note that
--   desugaring upholds the following properties regarding the
--   DataFlavor field:
--   
--   
--   
- If the DataFlavor is NewType, then there will be
--   exactly one DCon.
--   
- If the DataFlavor is TypeData, then there will be no
--   DDerivClauses, the DCxt will be empty, and the
--   DConFields in each DCon will be a NormalC where
--   each Bang is equal to Bang NoSourceUnpackedness
--   NoSourceStrictness.
--   
DDataD :: DataFlavor -> DCxt -> Name -> [DTyVarBndrVis] -> Maybe DKind -> [DCon] -> [DDerivClause] -> DDec
DTySynD :: Name -> [DTyVarBndrVis] -> DType -> DDec
DClassD :: DCxt -> Name -> [DTyVarBndrVis] -> [FunDep] -> [DDec] -> DDec

-- | Note that the Maybe [DTyVarBndrUnit] field is dropped
--   entirely when sweetened, so it is only useful for functions that
--   directly consume DDecs.
DInstanceD :: Maybe Overlap -> Maybe [DTyVarBndrUnit] -> DCxt -> DType -> [DDec] -> DDec
DForeignD :: DForeign -> DDec
DOpenTypeFamilyD :: DTypeFamilyHead -> DDec
DClosedTypeFamilyD :: DTypeFamilyHead -> [DTySynEqn] -> DDec
DDataFamilyD :: Name -> [DTyVarBndrVis] -> Maybe DKind -> DDec

-- | A data family instance declaration. Note that desugaring upholds the
--   following properties regarding the DataFlavor field:
--   
--   
--   
- If the DataFlavor is NewType, then there will be
--   exactly one DCon.
--   
- The DataFlavor will never be TypeData, as GHC does
--   not permit combining data families with type data.
--   
DDataInstD :: DataFlavor -> DCxt -> Maybe [DTyVarBndrUnit] -> DType -> Maybe DKind -> [DCon] -> [DDerivClause] -> DDec
DTySynInstD :: DTySynEqn -> DDec
DRoleAnnotD :: Name -> [Role] -> DDec

-- | Note that the Maybe [DTyVarBndrUnit] field is dropped
--   entirely when sweetened, so it is only useful for functions that
--   directly consume DDecs.
DStandaloneDerivD :: Maybe DDerivStrategy -> Maybe [DTyVarBndrUnit] -> DCxt -> DType -> DDec
DDefaultSigD :: Name -> DType -> DDec
DPatSynD :: Name -> PatSynArgs -> DPatSynDir -> DPat -> DDec
DPatSynSigD :: Name -> DPatSynType -> DDec
DKiSigD :: Name -> DKind -> DDec
DDefaultD :: [DType] -> DDec

-- | Corresponds to TH's DerivClause type.
data DDerivClause
DDerivClause :: Maybe DDerivStrategy -> DCxt -> DDerivClause

-- | Corresponds to TH's DerivStrategy type.
data DDerivStrategy

-- | A "standard" derived instance
DStockStrategy :: DDerivStrategy

-- | 
--   -XDeriveAnyClass
--   
DAnyclassStrategy :: DDerivStrategy

-- | 
--   -XGeneralizedNewtypeDeriving
--   
DNewtypeStrategy :: DDerivStrategy

-- | 
--   -XDerivingVia
--   
DViaStrategy :: DType -> DDerivStrategy

-- | Corresponds to TH's PatSynDir type
data DPatSynDir

-- | 
--   pattern P x {<-} p
--   
DUnidir :: DPatSynDir

-- | 
--   pattern P x {=} p
--   
DImplBidir :: DPatSynDir

-- | 
--   pattern P x {<-} p where P x = e
--   
DExplBidir :: [DClause] -> DPatSynDir

-- | Corresponds to TH's PatSynType type
type DPatSynType = DType

-- | Varieties of allowed instance overlap.
data Overlap

-- | May be overlapped by more specific instances
Overlappable :: Overlap

-- | May overlap a more general instance
Overlapping :: Overlap

-- | Both Overlapping and Overlappable
Overlaps :: Overlap

-- | Both Overlapping and Overlappable, and pick an arbitrary
--   one if multiple choices are available.
Incoherent :: Overlap

-- | A pattern synonym's argument type.
data PatSynArgs

-- | 
--   pattern P {x y z} = p
--   
PrefixPatSyn :: [Name] -> PatSynArgs

-- | 
--   pattern {x P y} = p
--   
InfixPatSyn :: Name -> Name -> PatSynArgs

-- | 
--   pattern P { {x,y,z} } = p
--   
RecordPatSyn :: [Name] -> PatSynArgs

-- | Is a data type or data instance declaration a newtype
--   declaration, a data declaration, or a type data
--   declaration?
data DataFlavor

-- | 
--   newtype
--   
Newtype :: DataFlavor

-- | 
--   data
--   
Data :: DataFlavor

-- | 
--   type data
--   
TypeData :: DataFlavor

-- | Corresponds to TH's TypeFamilyHead type
data DTypeFamilyHead
DTypeFamilyHead :: Name -> [DTyVarBndrVis] -> DFamilyResultSig -> Maybe InjectivityAnn -> DTypeFamilyHead

-- | Corresponds to TH's FamilyResultSig type
data DFamilyResultSig
DNoSig :: DFamilyResultSig
DKindSig :: DKind -> DFamilyResultSig
DTyVarSig :: DTyVarBndrUnit -> DFamilyResultSig

-- | Injectivity annotation
data InjectivityAnn
InjectivityAnn :: Name -> [Name] -> InjectivityAnn

-- | Corresponds to TH's Con type. Unlike Con, all
--   DCons 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 Maybe DKind, since
--   Haskell98-style data declaration syntax isn't used. Accordingly, there
--   are some differences between DCon and Con to keep in
--   mind:
--   
--   
--   
- Unlike ForallC, where the meaning of the TyVarBndrs
--   changes depending on whether it's followed by
--   GadtC/RecGadtC or not, the meaning of the
--   DTyVarBndrs in a DCon 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.
--   
data DCon

-- | The GADT result type
DCon :: [DTyVarBndrSpec] -> DCxt -> Name -> DConFields -> DType -> DCon

-- | A list of fields either for a standard data constructor or a record
--   data constructor.
data DConFields
DNormalC :: DDeclaredInfix -> [DBangType] -> DConFields
DRecC :: [DVarBangType] -> DConFields

-- | 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 Infix 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).
--   
type DDeclaredInfix = Bool

-- | Corresponds to TH's BangType type.
type DBangType = (Bang, DType)

-- | Corresponds to TH's VarBangType type.
type DVarBangType = (Name, Bang, DType)
data Bang

-- | 
--   C { {-# UNPACK #-} !}a
--   
Bang :: SourceUnpackedness -> SourceStrictness -> Bang

-- | SourceUnpackedness corresponds to unpack annotations found in
--   the source code.
--   
--   This may not agree with the annotations returned by
--   reifyConStrictness. See reifyConStrictness for more
--   information.
data SourceUnpackedness

-- | 
--   C a
--   
NoSourceUnpackedness :: SourceUnpackedness

-- | 
--   C { {-# NOUNPACK #-} } a
--   
SourceNoUnpack :: SourceUnpackedness

-- | 
--   C { {-# UNPACK #-} } a
--   
SourceUnpack :: SourceUnpackedness

-- | SourceStrictness corresponds to strictness annotations found in
--   the source code.
--   
--   This may not agree with the annotations returned by
--   reifyConStrictness. See reifyConStrictness for more
--   information.
data SourceStrictness

-- | 
--   C a
--   
NoSourceStrictness :: SourceStrictness

-- | 
--   C {~}a
--   
SourceLazy :: SourceStrictness

-- | 
--   C {!}a
--   
SourceStrict :: SourceStrictness

-- | Corresponds to TH's Foreign type.
data DForeign
DImportF :: Callconv -> Safety -> String -> Name -> DType -> DForeign
DExportF :: Callconv -> String -> Name -> DType -> DForeign

-- | Corresponds to TH's Pragma type.
data DPragma
DInlineP :: Name -> Inline -> RuleMatch -> Phases -> DPragma
DSpecialiseP :: Name -> DType -> Maybe Inline -> Phases -> DPragma
DSpecialiseInstP :: DType -> DPragma
DRuleP :: String -> Maybe [DTyVarBndrUnit] -> [DRuleBndr] -> DExp -> DExp -> Phases -> DPragma
DAnnP :: AnnTarget -> DExp -> DPragma
DLineP :: Int -> String -> DPragma
DCompleteP :: [Name] -> Maybe Name -> DPragma
DOpaqueP :: Name -> DPragma
DSCCP :: Name -> Maybe String -> DPragma

-- | Corresponds to TH's RuleBndr type.
data DRuleBndr
DRuleVar :: Name -> DRuleBndr
DTypedRuleVar :: Name -> DType -> DRuleBndr

-- | Corresponds to TH's TySynEqn type (to store type family
--   equations).
data DTySynEqn
DTySynEqn :: Maybe [DTyVarBndrUnit] -> DType -> DType -> DTySynEqn

-- | Corresponds to TH's Info type.
data DInfo
DTyConI :: DDec -> Maybe [DInstanceDec] -> DInfo

-- | The Maybe Name stores the name of the enclosing definition
--   (datatype, for a data constructor; class, for a method), if any
DVarI :: Name -> DType -> Maybe Name -> DInfo
DTyVarI :: Name -> DKind -> DInfo

-- | The Int is the arity; the Bool is whether this tycon
--   is unlifted.
DPrimTyConI :: Name -> Int -> Bool -> DInfo
DPatSynI :: Name -> DPatSynType -> DInfo
type DInstanceDec = DDec

-- | Role annotations
data Role

-- | 
--   nominal
--   
NominalR :: Role

-- | 
--   representational
--   
RepresentationalR :: Role

-- | 
--   phantom
--   
PhantomR :: Role

-- | 
--   _
--   
InferR :: Role
data AnnTarget
ModuleAnnotation :: AnnTarget
TypeAnnotation :: Name -> AnnTarget
ValueAnnotation :: Name -> AnnTarget

-- | 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 we define the following instances on old versions of GHC:
--   
--   
--   instance Desugar TyVarBndrSpec DTyVarBndrSpec
--   instance Desugar TyVarBndrUnit DTyVarBndrUnit
--   
--   
--   Prior to GHC 9.0, TyVarBndrSpec and TyVarBndrUnit are
--   simply type synonyms for TyVarBndr, so making the functional
--   dependencies bidirectional would cause these instances to be rejected.
class Desugar th ds | ds -> th
desugar :: (Desugar th ds, DsMonad q) => th -> q ds
sweeten :: Desugar th ds => ds -> th

-- | Desugar an expression
dsExp :: DsMonad q => Exp -> q DExp

-- | Desugar arbitrary Decs
dsDecs :: DsMonad q => [Dec] -> q [DDec]

-- | Desugar a type
dsType :: DsMonad q => Type -> q DType

-- | Desugar Info
dsInfo :: DsMonad q => Info -> q DInfo

-- | Desugar a pattern, along with processing a (desugared) expression that
--   is the entire scope of the variables bound in the pattern.
dsPatOverExp :: DsMonad q => Pat -> DExp -> q (DPat, DExp)

-- | Desugar multiple patterns. Like dsPatOverExp.
dsPatsOverExp :: DsMonad q => [Pat] -> DExp -> q ([DPat], DExp)

-- | Desugar a pattern, returning a list of (Name, DExp) pairs of extra
--   variables that must be bound within the scope of the pattern
dsPatX :: DsMonad q => Pat -> q (DPat, [(Name, DExp)])

-- | Desugar Decs that can appear in a let expression.
--   See the documentation for dsLetDec for an explanation of what
--   the return type represents.
dsLetDecs :: DsMonad q => [Dec] -> q ([DLetDec], DExp -> DExp)

-- | Desugar a TyVarBndr.
dsTvb :: DsMonad q => TyVarBndr_ flag -> q (DTyVarBndr flag)

-- | Desugar a TyVarBndrSpec.
dsTvbSpec :: DsMonad q => TyVarBndrSpec -> q DTyVarBndrSpec

-- | Desugar a TyVarBndrUnit.
dsTvbUnit :: DsMonad q => TyVarBndrUnit -> q DTyVarBndrUnit

-- | Desugar a TyVarBndrVis.
dsTvbVis :: DsMonad q => TyVarBndrVis -> q DTyVarBndrVis

-- | Desugar a Cxt
dsCxt :: DsMonad q => Cxt -> q DCxt

-- | Desugar a single Con.
--   
--   Because we always desugar Cons 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.)
dsCon :: DsMonad q => [DTyVarBndrVis] -> DType -> Con -> q [DCon]

-- | Desugar a Foreign.
dsForeign :: DsMonad q => Foreign -> q DForeign

-- | Desugar a Pragma.
dsPragma :: DsMonad q => Pragma -> q DPragma

-- | Desugar a RuleBndr.
dsRuleBndr :: DsMonad q => RuleBndr -> q DRuleBndr

-- | 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.
type PatM (q :: Type -> Type) = WriterT [(Name, DExp)] q

-- | Desugar a Pred, flattening any internal tuples
dsPred :: DsMonad q => Pred -> q DCxt

-- | Desugar a pattern.
dsPat :: forall (q :: Type -> Type). DsMonad q => Pat -> PatM q DPat

-- | Desugar a single Dec, perhaps producing multiple DDecs
dsDec :: DsMonad q => Dec -> q [DDec]

-- | Desugar a DataD, NewtypeD, or TypeDataD.
dsDataDec :: DsMonad q => DataFlavor -> Cxt -> Name -> [TyVarBndrVis] -> Maybe Kind -> [Con] -> [DerivingClause] -> q [DDec]

-- | Desugar a DataInstD or a NewtypeInstD.
dsDataInstDec :: DsMonad q => DataFlavor -> Cxt -> Name -> Maybe [TyVarBndrUnit] -> [TypeArg] -> Maybe Kind -> [Con] -> [DerivingClause] -> q [DDec]

-- | 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.)
type DerivingClause = DerivClause

-- | Desugar a DerivingClause.
dsDerivClause :: DsMonad q => DerivingClause -> q DDerivClause

-- | Desugar a single Dec that can appear in a let
--   expression. This produces the following output:
--   
--   
--   
- One or more DLetDecs (a single Dec can produce
--   multiple DLetDecs in the event of a value declaration that
--   binds multiple things by way of pattern matching.
--   
- A function of type DExp -> DExp, which
--   should be applied to the expression immediately following the
--   DLetDecs. This function prepends binding forms for any implicit
--   params that were bound in the argument Dec. (If no implicit
--   params are bound, this is simply the id 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 bindIP
--   @"x" new_x_val (ip @"x") can be formed. The implicit param
--   binders always come after all the other DLetDecs to support
--   parallel assignment of implicit params.
dsLetDec :: DsMonad q => Dec -> q ([DLetDec], DExp -> DExp)

-- | Desugar a list of matches for a case statement
dsMatches :: DsMonad q => Name -> [Match] -> q [DMatch]

-- | Desugar a Body
dsBody :: DsMonad q => Body -> [Dec] -> DExp -> q DExp

-- | Desugar guarded expressions
dsGuards :: DsMonad q => [(Guard, Exp)] -> DExp -> q DExp

-- | Desugar the Stmts in a do expression
dsDoStmts :: DsMonad q => Maybe ModName -> [Stmt] -> q DExp

-- | Desugar the Stmts in a list or monad comprehension
dsComp :: DsMonad q => [Stmt] -> q DExp

-- | Desugar clauses to a function definition
dsClauses :: DsMonad q => MatchContext -> [Clause] -> q [DClause]

-- | Desugar a BangType.
dsBangType :: DsMonad q => BangType -> q DBangType

-- | Desugar a VarBangType.
dsVarBangType :: DsMonad q => VarBangType -> q DVarBangType

-- | Desugar a TypeFamilyHead
dsTypeFamilyHead :: DsMonad q => TypeFamilyHead -> q DTypeFamilyHead

-- | Desugar a FamilyResultSig
dsFamilyResultSig :: DsMonad q => FamilyResultSig -> q DFamilyResultSig

-- | Desugar a PatSynDir. (Available only with GHC 8.2+)
dsPatSynDir :: DsMonad q => Name -> PatSynDir -> q DPatSynDir

-- | Desugar a TypeArg.
dsTypeArg :: DsMonad q => TypeArg -> q DTypeArg

-- | Expand all type synonyms and type families in the desugared abstract
--   syntax tree provided, where type family simplification is on a "best
--   effort" basis. Normally, the first parameter should have a type like
--   DExp or DLetDec.
expand :: (DsMonad q, Data a) => a -> q a

-- | 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.
expandType :: DsMonad q => DType -> q DType

-- | 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.
reifyWithWarning :: (Quasi q, MonadFail q) => Name -> q Info

-- | Add a list of declarations to be considered when reifying local
--   declarations.
withLocalDeclarations :: DsMonad q => [Dec] -> DsM q a -> q a

-- | Like reify, but safer and desugared. Uses local declarations
--   where available.
dsReify :: DsMonad q => Name -> q (Maybe DInfo)

-- | Like reifyType, but safer and desugared. Uses local
--   declarations where available.
dsReifyType :: DsMonad q => Name -> q (Maybe DType)

-- | 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_maybe :: DsMonad q => Name -> q (Maybe Info)

-- | Like reifyWithLocals_maybe, but throws an exception upon
--   failure, warning the user about separating splices.
reifyWithLocals :: DsMonad q => Name -> q Info

-- | 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.)
reifyFixityWithLocals :: DsMonad q => Name -> q (Maybe Fixity)

-- | 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_maybe :: DsMonad q => Name -> q (Maybe Type)

-- | Like reifyTypeWithLocals_maybe, but throws an exception upon
--   failure, warning the user about separating splices.
reifyTypeWithLocals :: DsMonad q => Name -> q Type

-- | 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.
lookupValueNameWithLocals :: DsMonad q => String -> q (Maybe Name)

-- | 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.
lookupTypeNameWithLocals :: DsMonad q => String -> q (Maybe Name)

-- | 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.
mkDataNameWithLocals :: DsMonad q => String -> q Name

-- | 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.
mkTypeNameWithLocals :: DsMonad q => String -> q Name

-- | 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, mkName
--   "==", where == 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.
reifyNameSpace :: DsMonad q => Name -> q (Maybe NameSpace)

-- | A DsMonad stores some list of declarations that should be
--   considered in scope. DsM is the prototypical inhabitant of
--   DsMonad.
class (Quasi m, MonadFail m) => DsMonad (m :: Type -> Type)

-- | Produce a list of local declarations.
localDeclarations :: DsMonad m => m [Dec]

-- | A convenient implementation of the DsMonad class. Use by
--   calling withLocalDeclarations.
data DsM (q :: Type -> Type) a

-- | Remove all nested pattern-matches within this expression. This also
--   removes all DTildePas and DBangPas. After this is
--   run, every pattern is guaranteed to be either a DConPa with
--   bare variables as arguments, a DLitPa, or a DWildPa.
scExp :: DsMonad q => DExp -> q DExp

-- | Like scExp, but for a DLetDec.
scLetDec :: DsMonad q => DLetDec -> q DLetDec

-- | Compute the free variables of a DType.
fvDType :: DType -> OSet Name

-- | Extract the term variables bound by a DPat.
--   
--   This does not extract any type variables bound by pattern
--   signatures, constructor patterns, or type patterns.
extractBoundNamesDPat :: DPat -> OSet Name

-- | Apply one DExp to a list of arguments
applyDExp :: DExp -> [DExp] -> DExp

-- | Convert a DPat to a DExp. Fails on DWildP and
--   DInvisP.
dPatToDExp :: DPat -> DExp

-- | Remove all wildcards from a pattern, replacing any wildcard with a
--   fresh variable
removeWilds :: DsMonad q => DPat -> q DPat

-- | Extract the DataFlavor, TyVarBndrs and constructors
--   given the Name of a type.
getDataD :: DsMonad q => String -> Name -> q (DataFlavor, [TyVarBndrVis], [Con])

-- | From the name of a data constructor, retrive the datatype definition
--   it is a part of.
dataConNameToDataName :: DsMonad q => Name -> q Name

-- | From the name of a data constructor, retrieve its definition as a
--   Con
dataConNameToCon :: DsMonad q => Name -> q Con

-- | Check if a name occurs anywhere within a TH tree.
nameOccursIn :: Data a => Name -> a -> Bool

-- | Extract all Names mentioned in a TH tree.
allNamesIn :: Data a => a -> [Name]

-- | If the declaration passed in is a DValD, creates new,
--   equivalent declarations such that the DPat in all DValDs
--   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.
flattenDValD :: Quasi q => DLetDec -> q [DLetDec]

-- | Produces DLetDecs representing the record selector functions
--   from the provided DCons.
--   
--   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 does not attempt to filter out "naughty"
--   record selectors—that is, records whose field types mention
--   existentially quantified type variables that do not appear in the
--   constructor's return type. Here is an example of a naughty record
--   selector:
--   
--   
--   data Some :: (Type -> Type) -> Type where
--     MkSome :: { getSome :: f a } -> Some f
--   
--   
--   GHC itself will not allow the use of getSome as a top-level
--   function due to its type f a mentioning the existential
--   variable a, but getRecordSelectors will return it
--   nonetheless. Ultimately, this design choice is a practical one, as
--   detecting which type variables are existential in Template Haskell is
--   difficult in the general case.
getRecordSelectors :: DsMonad q => [DCon] -> q [DLetDec]

-- | Like TH's lookupTypeName, but if this name is not bound, then
--   we assume it is declared in the current module.
mkTypeName :: Quasi q => String -> q Name

-- | Like TH's lookupDataName, but if this name is not bound, then
--   we assume it is declared in the current module.
mkDataName :: Quasi q => String -> q Name

-- | Like newName, but even more unique (unique across different splices),
--   and with unique nameBases. Precondition: the string is a
--   valid Haskell alphanumeric identifier (could be upper- or lower-case).
newUniqueName :: Quasi q => String -> q Name

-- | Make a tuple DExp from a list of DExps. Avoids using a
--   1-tuple.
mkTupleDExp :: [DExp] -> DExp

-- | Make a tuple DPat from a list of DPats. Avoids using a
--   1-tuple.
mkTupleDPat :: [DPat] -> DPat

-- | If decs is non-empty, delcare them in a let:
maybeDLetE :: [DLetDec] -> DExp -> DExp

-- | If matches is non-empty, make a case statement; otherwise make an
--   error statement
maybeDCaseE :: MatchContext -> DExp -> [DMatch] -> DExp

-- | Convert a list of DPat arguments and a DExp body into a
--   DLamE. This is needed since DLamE takes a list of
--   Names for its bound variables instead of DPats, so some
--   reorganization is needed.
mkDLamEFromDPats :: Quasi q => [DPat] -> DExp -> q DExp

-- | Extract the degree of a tuple Name.
--   
--   In addition to recognizing tuple syntax (e.g., ''(,,)), this
--   also recognizes the following:
--   
--   
--   
- ''Unit (for 0-tuples)
--   
- ''Solo/'MkSolo (for 1-tuples)
--   
- ''TupleN (for N-tuples)
--   
--   
--   In recent versions of GHC, ''() is a synonym for
--   ''Unit, ''(,) is a synonym for ''Tuple2,
--   and so on. As a result, we must check for ''Unit and
--   ''TupleN in tupleDegree_maybe to be thorough.
--   (There is no special tuple syntax for
--   ''Solo/'MkSolo, but we check them here as well for
--   the sake of completeness.)
tupleNameDegree_maybe :: Name -> Maybe Int

-- | Extract the degree of an unboxed sum Name.
--   
--   In addition to recognizing unboxed sum syntax (e.g., ''()),
--   this also recognizes ''SumN# (for unboxed N-ary
--   sum type constructors). In recent versions of GHC, ''Sum2# is
--   a synonym for ''(), ''Sum3# is a synonym for
--   ''(), and so on. As a result, we must check for
--   ''SumN# in unboxedSumNameDegree_maybe to be
--   thorough.
unboxedSumNameDegree_maybe :: Name -> Maybe Int

-- | Extract the degree of an unboxed tuple Name.
--   
--   In addition to recognizing unboxed tuple syntax (e.g., ''()),
--   this also recognizes the following:
--   
--   
--   
- ''Unit# (for unboxed 0-tuples)
--   
- ''Solo#/'Solo# (for unboxed 1-tuples)
--   
- ''TupleN# (for unboxed N-tuples)
--   
--   
--   In recent versions of GHC, ''(##) is a synonym for
--   ''Unit#, ''() is a synonym for ''Tuple2#,
--   and so on. As a result, we must check for ''Unit#, and
--   ''TupleN in unboxedTupleNameDegree_maybe to be
--   thorough. (There is no special unboxed tuple type constructor for
--   ''Solo#/'Solo#, but we check them here as well for
--   the sake of completeness.)
unboxedTupleNameDegree_maybe :: Name -> Maybe Int

-- | Returns True if the argument Name is that of Type
--   (or * or ★, to support older GHCs).
isTypeKindName :: Name -> Bool

-- | The Name of the kind Type. 2. The kind * on
--   older GHCs.
typeKindName :: Name

-- | 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.
bindIP :: forall (name :: Symbol) a r. a -> (IP name a => r) -> r

-- | 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.
mkExtraDKindBinders :: DsMonad q => DKind -> q [DTyVarBndrVis]

-- | Convert a DTyVarBndr into a DType
dTyVarBndrToDType :: DTyVarBndr flag -> DType

-- | Set the flag in a list of DTyVarBndrs. This is often useful in
--   contexts where one needs to re-use a list of DTyVarBndrs from
--   one flag setting to another flag setting. For example, in order to
--   re-use the DTyVarBndrs bound by a DDataD in a
--   DForallT, one can do the following:
--   
--   
--   case x of
--     DDataD _ _ _ tvbs _ _ _ ->
--       DForallT (DForallInvis (changeDTVFlags SpecifiedSpec tvbs)) ...
--   
changeDTVFlags :: newFlag -> [DTyVarBndr oldFlag] -> [DTyVarBndr newFlag]

-- | Take a list of DTypes, 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 of K will always appear to
--   the left of the free variables of A 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.
toposortTyVarsOf :: [DType] -> [DTyVarBndrUnit]

-- | Take a telescope of DTyVarBndrs, find the free variables in
--   their kinds, and sort them in reverse topological order to ensure that
--   they are well scoped. Because the argument list is assumed to be
--   telescoping, kind variables that are bound earlier in the list are not
--   returned. For example, this:
--   
--   
--   toposortKindVarsOfTvbs [a :: k, b :: Proxy a]
--   
--   
--   Will return [k], not [k, a], since a is
--   bound earlier by a :: k.
toposortKindVarsOfTvbs :: [DTyVarBndr flag] -> [DTyVarBndrUnit]

-- | The list of arguments in a function Type.
data FunArgs

-- | No more arguments.
FANil :: FunArgs

-- | A series of foralled type variables followed by a dot (if
--   ForallInvis) or an arrow (if ForallVis). For example,
--   the type variables a1 ... an in forall a1 ... an. r.
FAForalls :: ForallTelescope -> FunArgs -> FunArgs

-- | A series of constraint arguments followed by =>. For
--   example, the (c1, ..., cn) in (c1, ..., cn) => r.
FACxt :: Cxt -> FunArgs -> FunArgs

-- | An anonymous argument followed by an arrow. For example, the
--   a in a -> r.
FAAnon :: Type -> FunArgs -> FunArgs

-- | The type variable binders in a forall. This is not used by
--   the TH AST itself, but this is used as an intermediate data type in
--   FAForalls.
data ForallTelescope

-- | A visible forall (e.g., forall a -> {...}). These
--   do not have any notion of specificity, so we use () as a
--   placeholder value in the TyVarBndrs.
ForallVis :: [TyVarBndrUnit] -> ForallTelescope

-- | An invisible forall (e.g., forall a {b} c ->
--   {...}), where each binder has a Specificity.
ForallInvis :: [TyVarBndrSpec] -> ForallTelescope

-- | 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.
data VisFunArg

-- | A visible forall (e.g., forall a -> a).
VisFADep :: TyVarBndrUnit -> VisFunArg

-- | An anonymous argument followed by an arrow (e.g., a -> r).
VisFAAnon :: Type -> VisFunArg

-- | Filter the visible function arguments from a list of FunArgs.
filterVisFunArgs :: FunArgs -> [VisFunArg]

-- | Reconstruct an arrow Type from its argument and result types.
ravelType :: FunArgs -> Type -> Type

-- | Decompose a function Type into its arguments (the
--   FunArgs) and its result type (the 'Type).
unravelType :: Type -> (FunArgs, Type)

-- | The list of arguments in a function DType.
data DFunArgs

-- | No more arguments.
DFANil :: DFunArgs

-- | A series of foralled type variables followed by a dot (if
--   ForallInvis) or an arrow (if ForallVis). For example,
--   the type variables a1 ... an in forall a1 ... an. r.
DFAForalls :: DForallTelescope -> DFunArgs -> DFunArgs

-- | A series of constraint arguments followed by =>. For
--   example, the (c1, ..., cn) in (c1, ..., cn) => r.
DFACxt :: DCxt -> DFunArgs -> DFunArgs

-- | An anonymous argument followed by an arrow. For example, the
--   a in a -> r.
DFAAnon :: DType -> DFunArgs -> DFunArgs

-- | 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.
data DVisFunArg

-- | A visible forall (e.g., forall a -> a).
DVisFADep :: DTyVarBndrUnit -> DVisFunArg

-- | An anonymous argument followed by an arrow (e.g., a -> r).
DVisFAAnon :: DType -> DVisFunArg

-- | Filter the visible function arguments from a list of DFunArgs.
filterDVisFunArgs :: DFunArgs -> [DVisFunArg]

-- | Reconstruct an arrow DType from its argument and result types.
ravelDType :: DFunArgs -> DType -> DType

-- | Decompose a function DType into its arguments (the
--   DFunArgs) and its result type (the 'DType).
unravelDType :: DType -> (DFunArgs, DType)

-- | 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).
data TypeArg
TANormal :: Type -> TypeArg
TyArg :: Kind -> TypeArg

-- | Apply one Type to a list of arguments.
applyType :: Type -> [TypeArg] -> Type

-- | Filter the normal type arguments from a list of TypeArgs.
filterTANormals :: [TypeArg] -> [Type]

-- | Convert a TyVarBndrVis to a TypeArg. That is, convert a
--   binder with a BndrReq visibility to a TANormal and a
--   binder with BndrInvis visibility to a TyArg.
--   
--   If given a KindedTV, the resulting TypeArg will omit the
--   kind signature. Use tyVarBndrVisToTypeArgWithSig if you want to
--   preserve the kind signature.
tyVarBndrVisToTypeArg :: TyVarBndrVis -> TypeArg

-- | Convert a TyVarBndrVis to a TypeArg. That is, convert a
--   binder with a BndrReq visibility to a TANormal and a
--   binder with BndrInvis visibility to a TyArg.
--   
--   If given a KindedTV, the resulting TypeArg will preserve
--   the kind signature. Use tyVarBndrVisToTypeArg if you want to
--   omit the kind signature.
tyVarBndrVisToTypeArgWithSig :: TyVarBndrVis -> TypeArg

-- | Decompose an applied type into its individual components. For example,
--   this:
--   
--   
--   Proxy @Type Char
--   
--   
--   would be unfolded to this:
--   
--   
--   (ConT ''Proxy, [TyArg (ConT ''Type), TANormal (ConT ''Char)])
--   
--   
--   This process forgets about infix application, so both of these types:
--   
--   
--   Int :++: Int
--   (:++:) Int Int
--   
--   
--   will be unfolded to this:
--   
--   
--   (ConT ''(:+:), [TANormal (ConT ''Int), TANormal (ConT ''Int)])
--   
--   
--   This function should only be used after all UInfixT and
--   PromotedUInfixT types have been resolved (e.g., via
--   th-abstraction's resolveInfixT function).
unfoldType :: Type -> (Type, [TypeArg])

-- | 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.
data DTypeArg
DTANormal :: DType -> DTypeArg
DTyArg :: DKind -> DTypeArg

-- | Apply one DType to a list of arguments
applyDType :: DType -> [DTypeArg] -> DType

-- | Filter the normal type arguments from a list of DTypeArgs.
filterDTANormals :: [DTypeArg] -> [DType]

-- | Convert a DTyVarBndrVis to a DTypeArg. That is, convert
--   a binder with a BndrReq visibility to a DTANormal and a
--   binder with BndrInvis visibility to a DTyArg.
--   
--   If given a DKindedTV, the resulting DTypeArg will omit
--   the kind signature. Use dTyVarBndrVisToDTypeArgWithSig if you
--   want to preserve the kind signature.
dTyVarBndrVisToDTypeArg :: DTyVarBndrVis -> DTypeArg

-- | Convert a DTyVarBndrVis to a DTypeArg. That is, convert
--   a binder with a BndrReq visibility to a DTANormal and a
--   binder with BndrInvis visibility to a DTyArg.
--   
--   If given a DKindedTV, the resulting DTypeArg will
--   preserve the kind signature. Use dTyVarBndrVisToDTypeArg if you
--   want to omit the kind signature.
dTyVarBndrVisToDTypeArgWithSig :: DTyVarBndrVis -> DTypeArg

-- | Decompose an applied type into its individual components. For example,
--   this:
--   
--   
--   Proxy @Type Char
--   
--   
--   would be unfolded to this:
--   
--   
--   (DConT ''Proxy, [DTyArg (DConT ''Type), DTANormal (DConT ''Char)])
--   
unfoldDType :: DType -> (DType, [DTypeArg])

-- | Extract the names bound in a Stmt.
--   
--   This does not extract any type variables bound by pattern
--   signatures, constructor patterns, or type patterns.
extractBoundNamesStmt :: Stmt -> OSet Name

-- | Extract the names bound in a Dec that could appear in a
--   let expression.
--   
--   This does not extract any type variables bound by pattern
--   signatures, constructor patterns, or type patterns.
extractBoundNamesDec :: Dec -> OSet Name

-- | Extract the names bound in a Pat.
--   
--   This does not extract any type variables bound by pattern
--   signatures, constructor patterns, or type patterns.
extractBoundNamesPat :: Pat -> OSet Name
instance Language.Haskell.TH.Desugar.Desugar Language.Haskell.TH.Syntax.Exp Language.Haskell.TH.Desugar.AST.DExp
instance Language.Haskell.TH.Desugar.Desugar Language.Haskell.TH.Syntax.Cxt Language.Haskell.TH.Desugar.AST.DCxt
instance Language.Haskell.TH.Desugar.Desugar [Language.Haskell.TH.Syntax.Dec] [Language.Haskell.TH.Desugar.AST.DDec]
instance Language.Haskell.TH.Desugar.Desugar (Language.Haskell.TH.Syntax.TyVarBndr flag) (Language.Haskell.TH.Desugar.AST.DTyVarBndr flag)
instance Language.Haskell.TH.Desugar.Desugar Language.Haskell.TH.Desugar.Util.TypeArg Language.Haskell.TH.Desugar.Core.DTypeArg
instance Language.Haskell.TH.Desugar.Desugar Language.Haskell.TH.Syntax.Type Language.Haskell.TH.Desugar.AST.DType

-- | Historically, this module defined orphan Lift instances for
--   the data types in th-desugar. Nowadays, these instances are
--   defined alongside the data types themselves, so this module simply
--   re-exports the instances.
module Language.Haskell.TH.Desugar.Lift
