packages feed

th-abstraction 0.4.5.0 → 0.7.2.0

raw patch · 8 files changed

Files

ChangeLog.md view
@@ -1,5 +1,196 @@ # Revision history for th-abstraction +## 0.7.2.0 -- 2026.01.03+* Support GHC 9.14.++## 0.7.1.0 -- 2024.12.05+* Drop support for pre-8.0 versions of GHC.++## 0.7.0.0 -- 2024.03.17+* `DatatypeInfo` now has an additional `datatypeReturnKind` field. Most of the+  time, this will be `StarT`, but this can also be more exotic kinds such as+  `ConT ''UnliftedType` if dealing with primitive types, `UnliftedDatatypes`,+  or `UnliftedNewtypes`.+* `reifyDatatype` and related functions now support primitive types such as+  `Int#`. These will be reified as `DatatypeInfo`s with no `ConstructorInfo`s+  and with `Datatype` as the `datatypeVariant`.+* `normalizeCon` now takes a `Kind` argument representing the return kind of+  the parent data type. (This is sometimes necessary to determine which type+  variables in the data constructor are universal or existential, depending+  on if the variables appear in the return kind.)+* Fix a couple of bugs in which `normalizeDec` would return incorrect results+  for GADTs that use `forall`s in their return kind.++## 0.6.0.0 -- 2023.07.31+* Support building with `template-haskell-2.21.0.0` (GHC 9.8).+* Adapt to `TyVarBndr`s for type-level declarations changing their type from+  `TyVarBndr ()` to `TyVarBndr BndrVis` in `template-haskell`:++  * `Language.Haskell.TH.Datatype.TyVarBndr` now backports `type BndrVis = ()`,+    as well as `BndrReq` and `BndrInvis` pattern synonyms. These make it+    possible to write code involving `BndrVis` that is somewhat backwards+    compatible (but do see the caveats in the Haddocks for `BndrInvis`).+  * `Language.Haskell.TH.Datatype.TyVarBndr` also backports the following+    definitions:+    * The `type TyVarBndrVis = TyVarBndr BndrVis` type synonym.+    * The `DefaultBndrFlag` class, which can be used to write code that is+      polymorphic over `TyVarBndr` flags while still allowing the code to return+      a reasonable default value for the flag.+    * The `bndrReq` and `bndrInvis` definitions, which behave identically to+      `BndrReq` and `BndrInvis`.+  * `Language.Haskell.TH.Datatype.TyVarBndr` now defines the following utility+    functions, which are not present in `template-haskell`:+    * `plainTVReq`, `plainTVInvis`, `kindedTVReq`, and `kindedTVInvis`+      functions, which construct `PlainTV`s and `KindedTV`s with particular+      `BndrVis` flags.+    * An `elimTVFlag`, which behaves like `elimTV`, but where the continuation+      arguments also take a `flag` argument. (Note that the type of this+      function is slightly different on old versions of `template-haskell`.+      See the Haddocks for more.)+    * A `tvFlag` function, which extracts the `flag` from a `TyVarBndr`. (Note+      that the type of this function is slightly different on old versions of+      `template-haskell`. See the Haddocks for more.)+  * The types of the `dataDCompat` and `newtypeDCompat` functions have had+    their `[TyVarBndrUnit]` arguments changed to `[TyVarBndrVis]`, matching+    similar changes to `DataD` and `NewtypeD` in `template-haskell`.++  Because `BndrVis` is a synonym for `()` on pre-9.8 versions of GHC, this+  change is unlikely to break any existing code, provided that you build it+  with GHC 9.6 or earlier. If you build with GHC 9.8 or later, on the other+  hand, it is likely that you will need to update your existing code. Here are+  some possible ways that your code might fail to compile with GHC 9.8, along+  with some migration strategies:++  * Your code passes a `TyVarBndrUnit` in a place where a `TyVarBndrVis` is now+    expected in GHC 9.8, such as in the arguments to `dataDCompat`:++    ```hs+    import "template-haskell" Language.Haskell.TH+    import "th-abstraction"   Language.Haskell.TH.Datatype (dataDCompat)++    dec :: DecQ+    dec = dataDCompat (pure []) d [PlainTV a ()] [] []+      where+        d = mkName "d"+        a = mkName "a"+    ```++    With GHC 9.8, this will fail to compile with:++    ```+    error: [GHC-83865]+        • Couldn't match expected type ‘BndrVis’ with actual type ‘()’+        • In the second argument of ‘PlainTV’, namely ‘()’+          In the expression: PlainTV a ()+          In the third argument of ‘dataDCompat’, namely ‘[PlainTV a ()]’+      |+      | dec = dataDCompat (pure []) d [PlainTV a ()] [] []+      |                                          ^^+    ```++    Some possible ways to migrate this code include:++    * Use the `bndrReq` function or `BndrReq` pattern synonym in place of `()`,+      making sure to import them from `Language.Haskell.TH.Datatype.TyVarBndr`:++      ```hs+      ...+      import "th-abstraction" Language.Haskell.TH.Datatype.TyVarBndr++      dec :: DecQ+      dec = dataDCompat (pure []) d [PlainTV a bndrReq] [] []+      -- Or, alternatively:+      {-+      dec = dataDCompat (pure []) d [PlainTV a BndrReq] [] []+      -}+        where+          ...+      ```+    * Use the `plainTV` function from `Language.Haskell.TH.Datatype.TyVarBndr`,+      which is now sufficiently polymorphic to work as both a `TyVarBndrUnit`+      and a `TyVarBndrVis`:++      ```hs+      ...+      import Language.Haskell.TH.Datatype.TyVarBndr++      dec :: DecQ+      dec = dataDCompat (pure []) d [plainTV a] [] []+        where+          ...+      ```+  * You may have to replace some uses of `TyVarBndrUnit` with `TyVarBndrVis`+    in your code. For instance, this will no longer typecheck in GHC 9.8 for+    similar reasons to the previous example:++    ```hs+    import "template-haskell" Language.Haskell.TH+    import "th-abstraction"   Language.Haskell.TH.Datatype (dataDCompat)++    dec :: DecQ+    dec = dataDCompat (pure []) d tvbs [] []+      where+        tvbs :: [TyVarBndrUnit]+        tvbs = [plainTV a]++        d = mkName "d"+        a = mkName "a"+    ```++    Here is a version that will typecheck with GHC 9.8 and earlier:++    ```hs+    ...+    import "th-abstraction" Language.Haskell.TH.Datatype.TyVarBndr++    dec :: DecQ+    dec = dataDCompat (pure []) d tvbs [] []+      where+        tvbs :: [TyVarBndrVis]+        tvbs = [plainTV a]++        ...+    ```+  * In some cases, the `TyVarBndrUnit`s might come from another place in the+    code, e.g.,++    ```hs+    import "template-haskell" Language.Haskell.TH+    import "th-abstraction"   Language.Haskell.TH.Datatype (dataDCompat)++    dec :: [TyVarBndrUnit] -> DecQ+    dec tvbs = dataDCompat (pure []) d tvbs [] []+      where+        d = mkName "d"+    ```++    If it is not straightforward to change `dec`'s type to accept+    `[TyVarBndrVis]` as an argument, another viable option is to use the+    `changeTVFlags` function:++    ```hs+    ...+    import "th-abstraction" Language.Haskell.TH.Datatype.TyVarBndr++    dec :: [TyVarBndrUnit] -> DecQ+    dec tvbs = dataDCompat (pure []) d tvbs' [] []+      where+        tvbs' :: [TyVarBndrVis]+        tvbs' = changeTVFlags bndrReq tvbs++        ...+    ```++  This guide, while not comprehensive, should cover most of the common cases one+  will encounter when migrating their `th-abstraction` code to support GHC 9.8.++## 0.5.0.0 -- 2023.02.27+* Support the `TypeData` language extension added in GHC 9.6. The+  `DatatypeVariant` data type now has a separate `TypeData` constructor to+  represent `type data` declarations.+* Add a `Lift` instance for `th-abstraction`'s compatibility shim for+  `Specificity` when building with pre-9.0 versions of GHC.+ ## 0.4.5.0 -- 2022.09.12 * Fix a bug in which data family declarations with interesting return kinds   (e.g., `data family F :: Type -> Type`) would be reified incorrectly when
src/Language/Haskell/TH/Datatype.hs view
@@ -1,2246 +1,2277 @@-{-# Language CPP, DeriveDataTypeable #-}--#if MIN_VERSION_base(4,4,0)-#define HAS_GENERICS-{-# Language DeriveGeneric #-}-#endif--#if MIN_VERSION_template_haskell(2,12,0)-{-# Language Safe #-}-#elif __GLASGOW_HASKELL__ >= 702-{-# Language Trustworthy #-}-#endif--{-|-Module      : Language.Haskell.TH.Datatype-Description : Backwards-compatible interface to reified information about datatypes.-Copyright   : Eric Mertens 2017-2020-License     : ISC-Maintainer  : emertens@gmail.com--This module provides a flattened view of information about data types-and newtypes that can be supported uniformly across multiple versions-of the @template-haskell@ package.--Sample output for @'reifyDatatype' ''Maybe@--@-'DatatypeInfo'- { 'datatypeContext'   = []- , 'datatypeName'      = GHC.Base.Maybe- , 'datatypeVars'      = [ 'KindedTV' a_3530822107858468866 () 'StarT' ]- , 'datatypeInstTypes' = [ 'SigT' ('VarT' a_3530822107858468866) 'StarT' ]- , 'datatypeVariant'   = 'Datatype'- , 'datatypeCons'      =-     [ 'ConstructorInfo'-         { 'constructorName'       = GHC.Base.Nothing-         , 'constructorVars'       = []-         , 'constructorContext'    = []-         , 'constructorFields'     = []-         , 'constructorStrictness' = []-         , 'constructorVariant'    = 'NormalConstructor'-         }-     , 'ConstructorInfo'-         { 'constructorName'       = GHC.Base.Just-         , 'constructorVars'       = []-         , 'constructorContext'    = []-         , 'constructorFields'     = [ 'VarT' a_3530822107858468866 ]-         , 'constructorStrictness' = [ 'FieldStrictness'-                                         'UnspecifiedUnpackedness'-                                         'Lazy'-                                     ]-         , 'constructorVariant'    = 'NormalConstructor'-         }-     ]- }-@--Datatypes declared with GADT syntax are normalized to constructors with existentially-quantified type variables and equality constraints.---}-module Language.Haskell.TH.Datatype-  (-  -- * Types-    DatatypeInfo(..)-  , ConstructorInfo(..)-  , DatatypeVariant(..)-  , ConstructorVariant(..)-  , FieldStrictness(..)-  , Unpackedness(..)-  , Strictness(..)--  -- * Normalization functions-  , reifyDatatype-  , reifyConstructor-  , reifyRecord-  , normalizeInfo-  , normalizeDec-  , normalizeCon--  -- * 'DatatypeInfo' lookup functions-  , lookupByConstructorName-  , lookupByRecordName--  -- * Type variable manipulation-  , TypeSubstitution(..)-  , quantifyType-  , freeVariablesWellScoped-  , freshenFreeVariables--  -- * 'Pred' functions-  , equalPred-  , classPred-  , asEqualPred-  , asClassPred--  -- * Backward compatible data definitions-  , dataDCompat-  , newtypeDCompat-  , tySynInstDCompat-  , pragLineDCompat-  , arrowKCompat--  -- * Strictness annotations-  , isStrictAnnot-  , notStrictAnnot-  , unpackedAnnot--  -- * Type simplification-  , resolveTypeSynonyms-  , resolveKindSynonyms-  , resolvePredSynonyms-  , resolveInfixT--  -- * Fixities-  , reifyFixityCompat-  , showFixity-  , showFixityDirection--  -- * Convenience functions-  , unifyTypes-  , tvName-  , tvKind-  , datatypeType-  ) where--import           Data.Data (Typeable, Data)-import           Data.Foldable (foldMap, foldl')-import           Data.List (mapAccumL, nub, find, union, (\\))-import           Data.Map (Map)-import qualified Data.Map as Map-import           Data.Maybe-import qualified Data.Set as Set-import           Data.Set (Set)-import qualified Data.Traversable as T-import           Control.Monad-import           Language.Haskell.TH-#if MIN_VERSION_template_haskell(2,11,0)-                                     hiding (Extension(..))-#endif-import           Language.Haskell.TH.Datatype.Internal-import           Language.Haskell.TH.Datatype.TyVarBndr-import           Language.Haskell.TH.Lib (arrowK, starK) -- needed for th-2.4--#ifdef HAS_GENERICS-import           GHC.Generics (Generic)-#endif--#if !MIN_VERSION_base(4,8,0)-import           Control.Applicative (Applicative(..), (<$>))-import           Data.Monoid (Monoid(..))-#endif---- | Normalized information about newtypes and data types.------ 'DatatypeInfo' contains two fields, 'datatypeVars' and 'datatypeInstTypes',--- which encode information about the argument types. The simplest explanation--- is that 'datatypeVars' contains all the type /variables/ bound by the data--- type constructor, while 'datatypeInstTypes' contains the type /arguments/--- to the data type constructor. To be more precise:------ * For ADTs declared with @data@ and @newtype@, it will likely be the case---   that 'datatypeVars' and 'datatypeInstTypes' coincide. For instance, given---   @newtype Id a = MkId a@, in the 'DatatypeInfo' for @Id@ we would---   have @'datatypeVars' = ['KindedTV' a () 'StarT']@ and---   @'datatypeInstVars' = ['SigT' ('VarT' a) 'StarT']@.------   ADTs that leverage @PolyKinds@ may have more 'datatypeVars' than---   'datatypeInstTypes'. For instance, given @data Proxy (a :: k) = MkProxy@,---   in the 'DatatypeInfo' for @Proxy@ we would have---   @'datatypeVars' = ['KindedTV' k () 'StarT', 'KindedTV' a () ('VarT' k)]@---   (since there are two variables, @k@ and @a@), whereas---   @'datatypeInstTypes' = ['SigT' ('VarT' a) ('VarT' k)]@, since there is---   only one explicit type argument to @Proxy@.------ * For @data instance@s and @newtype instance@s of data families,---   'datatypeVars' and 'datatypeInstTypes' can be quite different. Here is---   an example to illustrate the difference:------   @---   data family F a b---   data instance F (Maybe c) (f x) = MkF c (f x)---   @------   Then in the 'DatatypeInfo' for @F@'s data instance, we would have:------   @---   'datatypeVars'      = [ 'KindedTV' c () 'StarT'---                         , 'KindedTV' f () 'StarT'---                         , 'KindedTV' x () 'StarT' ]---   'datatypeInstTypes' = [ 'AppT' ('ConT' ''Maybe) ('VarT' c)---                         , 'AppT' ('VarT' f) ('VarT' x) ]---   @-data DatatypeInfo = DatatypeInfo-  { datatypeContext   :: Cxt               -- ^ Data type context (deprecated)-  , datatypeName      :: Name              -- ^ Type constructor-  , datatypeVars      :: [TyVarBndrUnit]   -- ^ Type parameters-  , datatypeInstTypes :: [Type]            -- ^ Argument types-  , datatypeVariant   :: DatatypeVariant   -- ^ Extra information-  , datatypeCons      :: [ConstructorInfo] -- ^ Normalize constructor information-  }-  deriving (Show, Eq, Typeable, Data-#ifdef HAS_GENERICS-           ,Generic-#endif-           )---- | Possible variants of data type declarations.-data DatatypeVariant-  = Datatype        -- ^ Type declared with @data@-  | Newtype         -- ^ Type declared with @newtype@-  | DataInstance    -- ^ Type declared with @data instance@-  | NewtypeInstance -- ^ Type declared with @newtype instance@-  deriving (Show, Read, Eq, Ord, Typeable, Data-#ifdef HAS_GENERICS-           ,Generic-#endif-           )---- | Normalized information about constructors associated with newtypes and--- data types.-data ConstructorInfo = ConstructorInfo-  { constructorName       :: Name               -- ^ Constructor name-  , constructorVars       :: [TyVarBndrUnit]    -- ^ Constructor type parameters-  , constructorContext    :: Cxt                -- ^ Constructor constraints-  , constructorFields     :: [Type]             -- ^ Constructor fields-  , constructorStrictness :: [FieldStrictness]  -- ^ Constructor fields' strictness-                                                --   (Invariant: has the same length-                                                --   as constructorFields)-  , constructorVariant    :: ConstructorVariant -- ^ Extra information-  }-  deriving (Show, Eq, Typeable, Data-#ifdef HAS_GENERICS-           ,Generic-#endif-           )---- | Possible variants of data constructors.-data ConstructorVariant-  = NormalConstructor        -- ^ Constructor without field names-  | InfixConstructor         -- ^ Constructor without field names that is-                             --   declared infix-  | RecordConstructor [Name] -- ^ Constructor with field names-  deriving (Show, Eq, Ord, Typeable, Data-#ifdef HAS_GENERICS-           ,Generic-#endif-           )---- | Normalized information about a constructor field's @UNPACK@ and--- strictness annotations.------ Note that the interface for reifying strictness in Template Haskell changed--- considerably in GHC 8.0. The presentation in this library mirrors that which--- can be found in GHC 8.0 or later, whereas previously, unpackedness and--- strictness were represented with a single data type:------ @--- data Strict---   = IsStrict---   | NotStrict---   | Unpacked -- On GHC 7.4 or later--- @------ For backwards compatibility, we retrofit these constructors onto the--- following three values, respectively:------ @--- 'isStrictAnnot'  = 'FieldStrictness' 'UnspecifiedUnpackedness' 'Strict'--- 'notStrictAnnot' = 'FieldStrictness' 'UnspecifiedUnpackedness' 'UnspecifiedStrictness'--- 'unpackedAnnot'  = 'FieldStrictness' 'Unpack' 'Strict'--- @-data FieldStrictness = FieldStrictness-  { fieldUnpackedness :: Unpackedness-  , fieldStrictness   :: Strictness-  }-  deriving (Show, Eq, Ord, Typeable, Data-#ifdef HAS_GENERICS-           ,Generic-#endif-           )---- | Information about a constructor field's unpackedness annotation.-data Unpackedness-  = UnspecifiedUnpackedness -- ^ No annotation whatsoever-  | NoUnpack                -- ^ Annotated with @{\-\# NOUNPACK \#-\}@-  | Unpack                  -- ^ Annotated with @{\-\# UNPACK \#-\}@-  deriving (Show, Eq, Ord, Typeable, Data-#ifdef HAS_GENERICS-           ,Generic-#endif-           )---- | Information about a constructor field's strictness annotation.-data Strictness-  = UnspecifiedStrictness -- ^ No annotation whatsoever-  | Lazy                  -- ^ Annotated with @~@-  | Strict                -- ^ Annotated with @!@-  deriving (Show, Eq, Ord, Typeable, Data-#ifdef HAS_GENERICS-           ,Generic-#endif-           )--isStrictAnnot, notStrictAnnot, unpackedAnnot :: FieldStrictness-isStrictAnnot  = FieldStrictness UnspecifiedUnpackedness Strict-notStrictAnnot = FieldStrictness UnspecifiedUnpackedness UnspecifiedStrictness-unpackedAnnot  = FieldStrictness Unpack Strict---- | Construct a Type using the datatype's type constructor and type--- parameters. Kind signatures are removed.-datatypeType :: DatatypeInfo -> Type-datatypeType di-  = foldl AppT (ConT (datatypeName di))-  $ map stripSigT-  $ datatypeInstTypes di----- | Compute a normalized view of the metadata about a data type or newtype--- given a constructor.------ This function will accept any constructor (value or type) for a type--- declared with newtype or data. Value constructors must be used to--- lookup datatype information about /data instances/ and /newtype instances/,--- as giving the type constructor of a data family is often not enough to--- determine a particular data family instance.------ In addition, this function will also accept a record selector for a--- data type with a constructor which uses that record.------ GADT constructors are normalized into datatypes with explicit equality--- constraints. Note that no effort is made to distinguish between equalities of--- the same (homogeneous) kind and equalities between different (heterogeneous)--- kinds. For instance, the following GADT's constructors:------ @--- data T (a :: k -> *) where---   MkT1 :: T Proxy---   MkT2 :: T Maybe--- @------ will be normalized to the following equality constraints:------ @--- AppT (AppT EqualityT (VarT a)) (ConT Proxy) -- MkT1--- AppT (AppT EqualityT (VarT a)) (ConT Maybe) -- MkT2--- @------ But only the first equality constraint is well kinded, since in the second--- constraint, the kinds of @(a :: k -> *)@ and @(Maybe :: * -> *)@ are different.--- Trying to categorize which constraints need homogeneous or heterogeneous--- equality is tricky, so we leave that task to users of this library.------ This function will apply various bug-fixes to the output of the underlying--- @template-haskell@ library in order to provide a view of datatypes in--- as uniform a way as possible.-reifyDatatype ::-  Name {- ^ data type or constructor name -} ->-  Q DatatypeInfo-reifyDatatype n = normalizeInfo' "reifyDatatype" isReified =<< reify n---- | Compute a normalized view of the metadata about a constructor given its--- 'Name'. This is useful for scenarios when you don't care about the info for--- the enclosing data type.-reifyConstructor ::-  Name {- ^ constructor name -} ->-  Q ConstructorInfo-reifyConstructor conName = do-  dataInfo <- reifyDatatype conName-  return $ lookupByConstructorName conName dataInfo---- | Compute a normalized view of the metadata about a constructor given the--- 'Name' of one of its record selectors. This is useful for scenarios when you--- don't care about the info for the enclosing data type.-reifyRecord ::-  Name {- ^ record name -} ->-  Q ConstructorInfo-reifyRecord recordName = do-  dataInfo <- reifyDatatype recordName-  return $ lookupByRecordName recordName dataInfo---- | Given a 'DatatypeInfo', find the 'ConstructorInfo' corresponding to the--- 'Name' of one of its constructors.-lookupByConstructorName ::-  Name {- ^ constructor name -} ->-  DatatypeInfo {- ^ info for the datatype which has that constructor -} ->-  ConstructorInfo-lookupByConstructorName conName dataInfo =-  case find ((== conName) . constructorName) (datatypeCons dataInfo) of-    Just conInfo -> conInfo-    Nothing      -> error $ "Datatype " ++ nameBase (datatypeName dataInfo)-                         ++ " does not have a constructor named " ++ nameBase conName--- | Given a 'DatatypeInfo', find the 'ConstructorInfo' corresponding to the--- 'Name' of one of its constructors.-lookupByRecordName ::-  Name {- ^ record name -} ->-  DatatypeInfo {- ^ info for the datatype which has that constructor -} ->-  ConstructorInfo-lookupByRecordName recordName dataInfo =-  case find (conHasRecord recordName) (datatypeCons dataInfo) of-    Just conInfo -> conInfo-    Nothing      -> error $ "Datatype " ++ nameBase (datatypeName dataInfo)-                         ++ " does not have any constructors with a "-                         ++ "record selector named " ++ nameBase recordName---- | Normalize 'Info' for a newtype or datatype into a 'DatatypeInfo'.--- Fail in 'Q' otherwise.-normalizeInfo :: Info -> Q DatatypeInfo-normalizeInfo = normalizeInfo' "normalizeInfo" isn'tReified--normalizeInfo' :: String -> IsReifiedDec -> Info -> Q DatatypeInfo-normalizeInfo' entry reifiedDec i =-  case i of-    PrimTyConI{}                      -> bad "Primitive type not supported"-    ClassI{}                          -> bad "Class not supported"-#if MIN_VERSION_template_haskell(2,11,0)-    FamilyI DataFamilyD{} _           ->-#elif MIN_VERSION_template_haskell(2,7,0)-    FamilyI (FamilyD DataFam _ _ _) _ ->-#else-    TyConI (FamilyD DataFam _ _ _)    ->-#endif-                                         bad "Use a value constructor to reify a data family instance"-#if MIN_VERSION_template_haskell(2,7,0)-    FamilyI _ _                       -> bad "Type families not supported"-#endif-    TyConI dec                        -> normalizeDecFor reifiedDec dec-#if MIN_VERSION_template_haskell(2,11,0)-    DataConI name _ parent            -> reifyParent name parent-                                         -- NB: We do not pass the IsReifiedDec information here-                                         -- because there's no point. We have no choice but to-                                         -- call reify here, since we need to determine the-                                         -- parent data type/family.-#else-    DataConI name _ parent _          -> reifyParent name parent-#endif-#if MIN_VERSION_template_haskell(2,11,0)-    VarI recName recTy _              -> reifyRecordType recName recTy-                                         -- NB: Similarly, we do not pass the IsReifiedDec-                                         -- information here.-#else-    VarI recName recTy _ _            -> reifyRecordType recName recTy-#endif-    _                                 -> bad "Expected a type constructor"-  where-    bad msg = fail (entry ++ ": " ++ msg)---reifyParent :: Name -> Name -> Q DatatypeInfo-reifyParent con = reifyParentWith "reifyParent" p-  where-    p :: DatatypeInfo -> Bool-    p info = con `elem` map constructorName (datatypeCons info)--reifyRecordType :: Name -> Type -> Q DatatypeInfo-reifyRecordType recName recTy =-  let (_, _, argTys :|- _) = uncurryType recTy-  in case argTys of-       dataTy:_ -> decomposeDataType dataTy-       _        -> notRecSelFailure-  where-    decomposeDataType :: Type -> Q DatatypeInfo-    decomposeDataType ty =-      do case decomposeType ty of-           ConT parent :| _ -> reifyParentWith "reifyRecordType" p parent-           _                -> notRecSelFailure--    notRecSelFailure :: Q a-    notRecSelFailure = fail $-      "reifyRecordType: Not a record selector type: " ++-      nameBase recName ++ " :: " ++ show recTy--    p :: DatatypeInfo -> Bool-    p info = any (conHasRecord recName) (datatypeCons info)--reifyParentWith ::-  String                 {- ^ prefix for error messages -} ->-  (DatatypeInfo -> Bool) {- ^ predicate for finding the right-                              data family instance -}      ->-  Name                   {- ^ parent data type name -}     ->-  Q DatatypeInfo-reifyParentWith prefix p n =-  do info <- reify n-     case info of-#if !(MIN_VERSION_template_haskell(2,11,0))-       -- This unusual combination of Info and Dec is only possible to reify on-       -- GHC 7.0 and 7.2, when you try to reify a data family. Because there's-       -- no way to reify the data family *instances* on these versions of GHC,-       -- we have no choice but to fail.-       TyConI FamilyD{} -> dataFamiliesOnOldGHCsError-#endif-       TyConI dec -> normalizeDecFor isReified dec-#if MIN_VERSION_template_haskell(2,7,0)-       FamilyI dec instances ->-         do instances1 <- mapM (repairDataFam dec) instances-            instances2 <- mapM (normalizeDecFor isReified) instances1-            case find p instances2 of-              Just inst -> return inst-              Nothing   -> panic "lost the instance"-#endif-       _ -> panic "unexpected parent"-  where-    dataFamiliesOnOldGHCsError :: Q a-    dataFamiliesOnOldGHCsError = fail $-      prefix ++ ": Data family instances can only be reified with GHC 7.4 or later"--    panic :: String -> Q a-    panic message = fail $ "PANIC: " ++ prefix ++ " " ++ message--#if MIN_VERSION_template_haskell(2,8,0) && (!MIN_VERSION_template_haskell(2,10,0))---- A GHC 7.6-specific bug requires us to replace all occurrences of--- (ConT GHC.Prim.*) with StarT, or else Template Haskell will reject it.--- Luckily, (ConT GHC.Prim.*) only seems to occur in this one spot.-sanitizeStars :: Kind -> Kind-sanitizeStars = go-  where-    go :: Kind -> Kind-    go (AppT t1 t2)                 = AppT (go t1) (go t2)-    go (SigT t k)                   = SigT (go t) (go k)-    go (ConT n) | n == starKindName = StarT-    go t                            = t---- A version of repairVarKindsWith that does much more extra work to--- (1) eta-expand missing type patterns, and (2) ensure that the kind--- signatures for these new type patterns match accordingly.-repairVarKindsWith' :: [TyVarBndrUnit] -> Maybe Kind -> [Type] -> Q [Type]-repairVarKindsWith' dvars dkind ts =-  let kindVars                = freeVariables . map kindPart-      kindPart (KindedTV _ k) = [k]-      kindPart (PlainTV  _  ) = []--      nparams             = length dvars-      kparams             = kindVars dvars-      (tsKinds,tsNoKinds) = splitAt (length kparams) ts-      tsKinds'            = map sanitizeStars tsKinds-      extraTys            = drop (length tsNoKinds) (bndrParams dvars)-      ts'                 = tsNoKinds ++ extraTys -- eta-expand-  in fmap (applySubstitution (Map.fromList (zip kparams tsKinds'))) $-     repairVarKindsWith dvars dkind ts'----- Sadly, Template Haskell's treatment of data family instances leaves much--- to be desired. Here are some problems that we have to work around:------ 1. On all versions of GHC, TH leaves off the kind signatures on the---    type patterns of data family instances where a kind signature isn't---    specified explicitly. Here, we can use the parent data family's---    type variable binders to reconstruct the kind signatures if they---    are missing.--- 2. On GHC 7.6 and 7.8, TH will eta-reduce data instances. We can find---    the missing type variables on the data constructor.------ We opt to avoid propagating these new type variables through to the--- constructor now, but we will return to this task in normalizeCon.-repairDataFam ::-  Dec {- ^ family declaration   -} ->-  Dec {- ^ instance declaration -} ->-  Q Dec {- ^ instance declaration -}--repairDataFam-  (FamilyD _ _ dvars dk)-  (NewtypeInstD cx n ts con deriv) = do-    ts' <- repairVarKindsWith' dvars dk ts-    return $ NewtypeInstD cx n ts' con deriv-repairDataFam-  (FamilyD _ _ dvars dk)-  (DataInstD cx n ts cons deriv) = do-    ts' <- repairVarKindsWith' dvars dk ts-    return $ DataInstD cx n ts' cons deriv-#else-repairDataFam famD instD-# if MIN_VERSION_template_haskell(2,15,0)-      | DataFamilyD _ dvars dk <- famD-      , NewtypeInstD cx mbInstVars nts k c deriv <- instD-      , con :| ts <- decomposeType nts-      = do ts' <- repairVarKindsWith dvars dk ts-           return $ NewtypeInstD cx mbInstVars (foldl' AppT con ts') k c deriv--      | DataFamilyD _ dvars dk <- famD-      , DataInstD cx mbInstVars nts k c deriv <- instD-      , con :| ts <- decomposeType nts-      = do ts' <- repairVarKindsWith dvars dk ts-           return $ DataInstD cx mbInstVars (foldl' AppT con ts') k c deriv-# elif MIN_VERSION_template_haskell(2,11,0)-      | DataFamilyD _ dvars dk <- famD-      , NewtypeInstD cx n ts k c deriv <- instD-      = do ts' <- repairVarKindsWith dvars dk ts-           return $ NewtypeInstD cx n ts' k c deriv--      | DataFamilyD _ dvars dk <- famD-      , DataInstD cx n ts k c deriv <- instD-      = do ts' <- repairVarKindsWith dvars dk ts-           return $ DataInstD cx n ts' k c deriv-# else-      | FamilyD _ _ dvars dk <- famD-      , NewtypeInstD cx n ts c deriv <- instD-      = do ts' <- repairVarKindsWith dvars dk ts-           return $ NewtypeInstD cx n ts' c deriv--      | FamilyD _ _ dvars dk <- famD-      , DataInstD cx n ts c deriv <- instD-      = do ts' <- repairVarKindsWith dvars dk ts-           return $ DataInstD cx n ts' c deriv-# endif-#endif-repairDataFam _ instD = return instD---- | @'repairVarKindsWith' tvbs mbKind ts@ returns @ts@, but where each element--- has an explicit kind signature taken from a 'TyVarBndr' in the corresponding--- position in @tvbs@, or from the corresponding kind argument in 'mbKind' if--- there aren't enough 'TyVarBndr's available. An example where @tvbs@ can be--- shorter than @ts@ can be found in this example from #95:------ @--- data family F :: Type -> Type--- data instance F a = C--- @------ The @F@ has no type variable binders in its @data family@ declaration, and--- it has a return kind of @Type -> Type@. As a result, we pair up @Type@ with--- @VarT a@ to get @SigT a (ConT ''Type)@.-repairVarKindsWith :: [TyVarBndrUnit] -> Maybe Kind -> [Type] -> Q [Type]-repairVarKindsWith tvbs mbKind ts = do-  extra_tvbs <- mkExtraKindBinders $ fromMaybe starK mbKind-  -- This list should be the same length as @ts@. If it isn't, something has-  -- gone terribly wrong.-  let tvbs' = tvbs ++ extra_tvbs-  return $ zipWith stealKindForType tvbs' ts---- If a VarT is missing an explicit kind signature, steal it from a TyVarBndr.-stealKindForType :: TyVarBndr_ flag -> Type -> Type-stealKindForType tvb t@VarT{} = SigT t (tvKind tvb)-stealKindForType _   t        = t---- | Normalize 'Dec' for a newtype or datatype into a 'DatatypeInfo'.--- Fail in 'Q' otherwise.------ Beware: 'normalizeDec' can have surprising behavior when it comes to fixity.--- For instance, if you have this quasiquoted data declaration:------ @--- [d| infix 5 :^^:---     data Foo where---       (:^^:) :: Int -> Int -> Foo |]--- @------ Then if you pass the 'Dec' for @Foo@ to 'normalizeDec' without splicing it--- in a previous Template Haskell splice, then @(:^^:)@ will be labeled a 'NormalConstructor'--- instead of an 'InfixConstructor'. This is because Template Haskell has no way to--- reify the fixity declaration for @(:^^:)@, so it must assume there isn't one. To--- work around this behavior, use 'reifyDatatype' instead.-normalizeDec :: Dec -> Q DatatypeInfo-normalizeDec = normalizeDecFor isn'tReified--normalizeDecFor :: IsReifiedDec -> Dec -> Q DatatypeInfo-normalizeDecFor isReified dec =-  case dec of-#if MIN_VERSION_template_haskell(2,12,0)-    NewtypeD context name tyvars mbKind con _derives ->-      normalizeDataD context name tyvars mbKind [con] Newtype-    DataD context name tyvars mbKind cons _derives ->-      normalizeDataD context name tyvars mbKind cons Datatype-# if MIN_VERSION_template_haskell(2,15,0)-    NewtypeInstD context mbTyvars nameInstTys mbKind con _derives ->-      normalizeDataInstDPostTH2'15 "newtype" context mbTyvars nameInstTys-                                   mbKind [con] NewtypeInstance-    DataInstD context mbTyvars nameInstTys mbKind cons _derives ->-      normalizeDataInstDPostTH2'15 "data" context mbTyvars nameInstTys-                                   mbKind cons DataInstance-# else-    NewtypeInstD context name instTys mbKind con _derives ->-      normalizeDataInstDPreTH2'15 context name instTys mbKind [con] NewtypeInstance-    DataInstD context name instTys mbKind cons _derives ->-      normalizeDataInstDPreTH2'15 context name instTys mbKind cons DataInstance-# endif-#elif MIN_VERSION_template_haskell(2,11,0)-    NewtypeD context name tyvars mbKind con _derives ->-      normalizeDataD context name tyvars mbKind [con] Newtype-    DataD context name tyvars mbKind cons _derives ->-      normalizeDataD context name tyvars mbKind cons Datatype-    NewtypeInstD context name instTys mbKind con _derives ->-      normalizeDataInstDPreTH2'15 context name instTys mbKind [con] NewtypeInstance-    DataInstD context name instTys mbKind cons _derives ->-      normalizeDataInstDPreTH2'15 context name instTys mbKind cons DataInstance-#else-    NewtypeD context name tyvars con _derives ->-      normalizeDataD context name tyvars Nothing [con] Newtype-    DataD context name tyvars cons _derives ->-      normalizeDataD context name tyvars Nothing cons Datatype-    NewtypeInstD context name instTys con _derives ->-      normalizeDataInstDPreTH2'15 context name instTys Nothing [con] NewtypeInstance-    DataInstD context name instTys cons _derives ->-      normalizeDataInstDPreTH2'15 context name instTys Nothing cons DataInstance-#endif-    _ -> fail "normalizeDecFor: DataD or NewtypeD required"-  where-    -- We only need to repair reified declarations for data family instances.-    repair13618' :: DatatypeInfo -> Q DatatypeInfo-    repair13618' di@DatatypeInfo{datatypeVariant = variant}-      | isReified && isFamInstVariant variant-      = repair13618 di-      | otherwise-      = return di--    -- Given a data type's instance types and kind, compute its free variables.-    datatypeFreeVars :: [Type] -> Maybe Kind -> [TyVarBndrUnit]-    datatypeFreeVars instTys mbKind =-      freeVariablesWellScoped $ instTys ++-#if MIN_VERSION_template_haskell(2,8,0)-                                           maybeToList mbKind-#else-                                           [] -- No kind variables-#endif--    normalizeDataD :: Cxt -> Name -> [TyVarBndrUnit] -> Maybe Kind-                   -> [Con] -> DatatypeVariant -> Q DatatypeInfo-    normalizeDataD context name tyvars mbKind cons variant =-      let params = bndrParams tyvars in-      normalize' context name (datatypeFreeVars params mbKind)-                 params mbKind cons variant--    normalizeDataInstDPostTH2'15-      :: String -> Cxt -> Maybe [TyVarBndrUnit] -> Type -> Maybe Kind-      -> [Con] -> DatatypeVariant -> Q DatatypeInfo-    normalizeDataInstDPostTH2'15 what context mbTyvars nameInstTys-                                 mbKind cons variant =-      case decomposeType nameInstTys of-        ConT name :| instTys ->-          normalize' context name-                     (fromMaybe (datatypeFreeVars instTys mbKind) mbTyvars)-                     instTys mbKind cons variant-        _ -> fail $ "Unexpected " ++ what ++ " instance head: " ++ pprint nameInstTys--    normalizeDataInstDPreTH2'15-      :: Cxt -> Name -> [Type] -> Maybe Kind-      -> [Con] -> DatatypeVariant -> Q DatatypeInfo-    normalizeDataInstDPreTH2'15 context name instTys mbKind cons variant =-      normalize' context name (datatypeFreeVars instTys mbKind)-                 instTys mbKind cons variant--    -- The main worker of this function.-    normalize' :: Cxt -> Name -> [TyVarBndrUnit] -> [Type] -> Maybe Kind-               -> [Con] -> DatatypeVariant -> Q DatatypeInfo-    normalize' context name tvbs instTys mbKind cons variant = do-      extra_tvbs <- mkExtraKindBinders $ fromMaybe starK mbKind-      let tvbs'    = tvbs ++ extra_tvbs-          instTys' = instTys ++ bndrParams extra_tvbs-      dec <- normalizeDec' isReified context name tvbs' instTys' cons variant-      repair13618' $ giveDIVarsStarKinds isReified dec---- | 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@.--- 'mkExtraKindBinders' 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.-mkExtraKindBinders :: Kind -> Q [TyVarBndrUnit]-mkExtraKindBinders kind = do-  kind' <- resolveKindSynonyms kind-  let (_, _, args :|- _) = uncurryKind kind'-  names <- replicateM (length args) (newName "x")-  return $ zipWith kindedTV names args---- | Is a declaration for a @data instance@ or @newtype instance@?-isFamInstVariant :: DatatypeVariant -> Bool-isFamInstVariant dv =-  case dv of-    Datatype        -> False-    Newtype         -> False-    DataInstance    -> True-    NewtypeInstance -> True--bndrParams :: [TyVarBndr_ flag] -> [Type]-bndrParams = map $ elimTV VarT (\n k -> SigT (VarT n) k)---- | Remove the outermost 'SigT'.-stripSigT :: Type -> Type-stripSigT (SigT t _) = t-stripSigT t          = t---normalizeDec' ::-  IsReifiedDec    {- ^ Is this a reified 'Dec'? -} ->-  Cxt             {- ^ Datatype context         -} ->-  Name            {- ^ Type constructor         -} ->-  [TyVarBndrUnit] {- ^ Type parameters          -} ->-  [Type]          {- ^ Argument types           -} ->-  [Con]           {- ^ Constructors             -} ->-  DatatypeVariant {- ^ Extra information        -} ->-  Q DatatypeInfo-normalizeDec' reifiedDec context name params instTys cons variant =-  do cons' <- concat <$> mapM (normalizeConFor reifiedDec name params instTys variant) cons-     return DatatypeInfo-       { datatypeContext   = context-       , datatypeName      = name-       , datatypeVars      = params-       , datatypeInstTypes = instTys-       , datatypeCons      = cons'-       , datatypeVariant   = variant-       }---- | Normalize a 'Con' into a 'ConstructorInfo'. This requires knowledge of--- the type and parameters of the constructor, as well as whether the constructor--- is for a data family instance, as extracted from the outer--- 'Dec'.-normalizeCon ::-  Name            {- ^ Type constructor  -} ->-  [TyVarBndrUnit] {- ^ Type parameters   -} ->-  [Type]          {- ^ Argument types    -} ->-  DatatypeVariant {- ^ Extra information -} ->-  Con             {- ^ Constructor       -} ->-  Q [ConstructorInfo]-normalizeCon = normalizeConFor isn'tReified--normalizeConFor ::-  IsReifiedDec    {- ^ Is this a reified 'Dec'? -} ->-  Name            {- ^ Type constructor         -} ->-  [TyVarBndrUnit] {- ^ Type parameters          -} ->-  [Type]          {- ^ Argument types           -} ->-  DatatypeVariant {- ^ Extra information        -} ->-  Con             {- ^ Constructor              -} ->-  Q [ConstructorInfo]-normalizeConFor reifiedDec typename params instTys variant =-  fmap (map (giveCIVarsStarKinds reifiedDec)) . dispatch-  where-    -- A GADT constructor is declared infix when:-    ---    -- 1. Its name uses operator syntax (e.g., (:*:))-    -- 2. It has exactly two fields-    -- 3. It has a programmer-supplied fixity declaration-    checkGadtFixity :: [Type] -> Name -> Q ConstructorVariant-    checkGadtFixity ts n = do-#if MIN_VERSION_template_haskell(2,11,0)-      -- Don't call reifyFixityCompat here! We need to be able to distinguish-      -- between a default fixity and an explicit @infixl 9@.-      mbFi <- return Nothing `recover` reifyFixity n-      let userSuppliedFixity = isJust mbFi-#else-      -- On old GHCs, there is a bug where infix GADT constructors will-      -- mistakenly be marked as (ForallC (NormalC ...)) instead of-      -- (ForallC (InfixC ...)). This is especially annoying since on these-      -- versions of GHC, Template Haskell doesn't grant the ability to query-      -- whether a constructor was given a user-supplied fixity declaration.-      -- Rather, you can only check the fixity that GHC ultimately decides on-      -- for a constructor, regardless of whether it was a default fixity or-      -- it was user-supplied.-      ---      -- We can approximate whether a fixity was user-supplied by checking if-      -- it is not equal to defaultFixity (infixl 9). Unfortunately,-      -- there is no way to distinguish between a user-supplied fixity of-      -- infixl 9 and the fixity that GHC defaults to, so we cannot properly-      -- handle that case.-      mbFi <- reifyFixityCompat n-      let userSuppliedFixity = isJust mbFi && mbFi /= Just defaultFixity-#endif-      return $ if isInfixDataCon (nameBase n)-                  && length ts == 2-                  && userSuppliedFixity-               then InfixConstructor-               else NormalConstructor--    -- Checks if a String names a valid Haskell infix data-    -- constructor (i.e., does it begin with a colon?).-    isInfixDataCon :: String -> Bool-    isInfixDataCon (':':_) = True-    isInfixDataCon _       = False--    dispatch :: Con -> Q [ConstructorInfo]-    dispatch =-      let defaultCase :: Con -> Q [ConstructorInfo]-          defaultCase = go [] [] False-            where-              go :: [TyVarBndrUnit]-                 -> Cxt-                 -> Bool -- Is this a GADT? (see the documentation for-                         -- for checkGadtFixity)-                 -> Con-                 -> Q [ConstructorInfo]-              go tyvars context gadt c =-                case c of-                  NormalC n xs -> do-                    let (bangs, ts) = unzip xs-                        stricts     = map normalizeStrictness bangs-                    fi <- if gadt-                             then checkGadtFixity ts n-                             else return NormalConstructor-                    return [ConstructorInfo n tyvars context ts stricts fi]-                  InfixC l n r ->-                    let (bangs, ts) = unzip [l,r]-                        stricts     = map normalizeStrictness bangs in-                    return [ConstructorInfo n tyvars context ts stricts-                                            InfixConstructor]-                  RecC n xs ->-                    let fns     = takeFieldNames xs-                        stricts = takeFieldStrictness xs in-                    return [ConstructorInfo n tyvars context-                              (takeFieldTypes xs) stricts (RecordConstructor fns)]-                  ForallC tyvars' context' c' ->-                    go (changeTVFlags () tyvars'++tyvars) (context'++context) True c'-#if MIN_VERSION_template_haskell(2,11,0)-                  GadtC ns xs innerType ->-                    let (bangs, ts) = unzip xs-                        stricts     = map normalizeStrictness bangs in-                    gadtCase ns innerType ts stricts (checkGadtFixity ts)-                  RecGadtC ns xs innerType ->-                    let fns     = takeFieldNames xs-                        stricts = takeFieldStrictness xs in-                    gadtCase ns innerType (takeFieldTypes xs) stricts-                             (const $ return $ RecordConstructor fns)-                where-                  gadtCase = normalizeGadtC typename params instTys tyvars context-#endif-#if MIN_VERSION_template_haskell(2,8,0) && (!MIN_VERSION_template_haskell(2,10,0))-          dataFamCompatCase :: Con -> Q [ConstructorInfo]-          dataFamCompatCase = go []-            where-              go tyvars c =-                case c of-                  NormalC n xs ->-                    let stricts = map (normalizeStrictness . fst) xs in-                    dataFamCase' n stricts NormalConstructor-                  InfixC l n r ->-                    let stricts = map (normalizeStrictness . fst) [l,r] in-                    dataFamCase' n stricts InfixConstructor-                  RecC n xs ->-                    let stricts = takeFieldStrictness xs in-                    dataFamCase' n stricts-                                 (RecordConstructor (takeFieldNames xs))-                  ForallC tyvars' context' c' ->-                    go (tyvars'++tyvars) c'--          dataFamCase' :: Name -> [FieldStrictness]-                       -> ConstructorVariant-                       -> Q [ConstructorInfo]-          dataFamCase' n stricts variant = do-            mbInfo <- reifyMaybe n-            case mbInfo of-              Just (DataConI _ ty _ _) -> do-                let (tyvars, context, argTys :|- returnTy) = uncurryType ty-                returnTy' <- resolveTypeSynonyms returnTy-                -- Notice that we've ignored the TyVarBndrs, Cxt and argument-                -- Types from the Con argument above, as they might be scoped-                -- over eta-reduced variables. Instead of trying to figure out-                -- what the eta-reduced variables should be substituted with-                -- post facto, we opt for the simpler approach of using the-                -- context and argument types from the reified constructor-                -- Info, which will at least be correctly scoped. This will-                -- make the task of substituting those types with the variables-                -- we put in place of the eta-reduced variables-                -- (in normalizeDec) much easier.-                normalizeGadtC typename params instTys tyvars context [n]-                               returnTy' argTys stricts (const $ return variant)-              _ -> fail $ unlines-                     [ "normalizeCon: Cannot reify constructor " ++ nameBase n-                     , "You are likely calling normalizeDec on GHC 7.6 or 7.8 on a data family"-                     , "whose type variables have been eta-reduced due to GHC Trac #9692."-                     , "Unfortunately, without being able to reify the constructor's type,"-                     , "there is no way to recover the eta-reduced type variables in general."-                     , "A recommended workaround is to use reifyDatatype instead."-                     ]--          -- A very ad hoc way of determining if we need to perform some extra passes-          -- to repair an eta-reduction bug for data family instances that only occurs-          -- with GHC 7.6 and 7.8. We want to avoid doing these passes if at all possible,-          -- since they require reifying extra information, and reifying during-          -- normalization can be problematic for locally declared Template Haskell-          -- splices (see ##22).-          mightHaveBeenEtaReduced :: [Type] -> Bool-          mightHaveBeenEtaReduced ts =-            case unsnoc ts of-              Nothing -> False-              Just (initTs :|- lastT) ->-                case varTName lastT of-                  Nothing -> False-                  Just n  -> not (n `elem` freeVariables initTs)--          -- If the list is empty returns 'Nothing', otherwise returns the-          -- 'init' and the 'last'.-          unsnoc :: [a] -> Maybe (NonEmptySnoc a)-          unsnoc [] = Nothing-          unsnoc (x:xs) = case unsnoc xs of-            Just (a :|- b) -> Just ((x:a) :|- b)-            Nothing        -> Just ([]    :|- x)--          -- If a Type is a VarT, find Just its Name. Otherwise, return Nothing.-          varTName :: Type -> Maybe Name-          varTName (SigT t _) = varTName t-          varTName (VarT n)   = Just n-          varTName _          = Nothing--      in case variant of-           -- On GHC 7.6 and 7.8, there's quite a bit of post-processing that-           -- needs to be performed to work around an old bug that eta-reduces the-           -- type patterns of data families (but only for reified data family instances).-           DataInstance-             | reifiedDec, mightHaveBeenEtaReduced instTys-             -> dataFamCompatCase-           NewtypeInstance-             | reifiedDec, mightHaveBeenEtaReduced instTys-             -> dataFamCompatCase-           _ -> defaultCase-#else-      in defaultCase-#endif--#if MIN_VERSION_template_haskell(2,11,0)-normalizeStrictness :: Bang -> FieldStrictness-normalizeStrictness (Bang upk str) =-  FieldStrictness (normalizeSourceUnpackedness upk)-                  (normalizeSourceStrictness str)-  where-    normalizeSourceUnpackedness :: SourceUnpackedness -> Unpackedness-    normalizeSourceUnpackedness NoSourceUnpackedness = UnspecifiedUnpackedness-    normalizeSourceUnpackedness SourceNoUnpack       = NoUnpack-    normalizeSourceUnpackedness SourceUnpack         = Unpack--    normalizeSourceStrictness :: SourceStrictness -> Strictness-    normalizeSourceStrictness NoSourceStrictness = UnspecifiedStrictness-    normalizeSourceStrictness SourceLazy         = Lazy-    normalizeSourceStrictness SourceStrict       = Strict-#else-normalizeStrictness :: Strict -> FieldStrictness-normalizeStrictness IsStrict  = isStrictAnnot-normalizeStrictness NotStrict = notStrictAnnot-# if MIN_VERSION_template_haskell(2,7,0)-normalizeStrictness Unpacked  = unpackedAnnot-# endif-#endif--normalizeGadtC ::-  Name              {- ^ Type constructor             -} ->-  [TyVarBndrUnit]   {- ^ Type parameters              -} ->-  [Type]            {- ^ Argument types               -} ->-  [TyVarBndrUnit]   {- ^ Constructor parameters       -} ->-  Cxt               {- ^ Constructor context          -} ->-  [Name]            {- ^ Constructor names            -} ->-  Type              {- ^ Declared type of constructor -} ->-  [Type]            {- ^ Constructor field types      -} ->-  [FieldStrictness] {- ^ Constructor field strictness -} ->-  (Name -> Q ConstructorVariant)-                    {- ^ Determine a constructor variant-                         from its 'Name' -}              ->-  Q [ConstructorInfo]-normalizeGadtC typename params instTys tyvars context names innerType-               fields stricts getVariant =-  do -- It's possible that the constructor has implicitly quantified type-     -- variables, such as in the following example (from #58):-     ---     --   [d| data Foo where-     --         MkFoo :: a -> Foo |]-     ---     -- normalizeGadtC assumes that all type variables have binders, however,-     -- so we use freeVariablesWellScoped to obtain the implicit type-     -- variables' binders before proceeding.-     let implicitTyvars = freeVariablesWellScoped-                          [curryType (changeTVFlags SpecifiedSpec tyvars)-                                     context fields innerType]-         allTyvars = implicitTyvars ++ tyvars--     -- Due to GHC Trac #13885, it's possible that the type variables bound by-     -- a GADT constructor will shadow those that are bound by the data type.-     -- This function assumes this isn't the case in certain parts (e.g., when-     -- mergeArguments is invoked), so we do an alpha-renaming of the-     -- constructor-bound variables before proceeding. See #36 for an example-     -- of what can go wrong if this isn't done.-     let conBoundNames =-           concatMap (\tvb -> tvName tvb:freeVariables (tvKind tvb)) allTyvars-     conSubst <- T.sequence $ Map.fromList [ (n, newName (nameBase n))-                                           | n <- conBoundNames ]-     let conSubst'     = fmap VarT conSubst-         renamedTyvars =-           map (elimTV (\n   -> plainTV  (conSubst Map.! n))-                       (\n k -> kindedTV (conSubst Map.! n)-                                         (applySubstitution conSubst' k))) allTyvars-         renamedContext   = applySubstitution conSubst' context-         renamedInnerType = applySubstitution conSubst' innerType-         renamedFields    = applySubstitution conSubst' fields--     innerType' <- resolveTypeSynonyms renamedInnerType-     case decomposeType innerType' of-       ConT innerTyCon :| ts | typename == innerTyCon ->--         let (substName, context1) =-               closeOverKinds (kindsOfFVsOfTvbs renamedTyvars)-                              (kindsOfFVsOfTvbs params)-                              (mergeArguments instTys ts)-             subst    = VarT <$> substName-             exTyvars = [ tv | tv <- renamedTyvars, Map.notMember (tvName tv) subst ]--             -- The use of substTyVarBndrKinds below will never capture, as the-             -- range of the substitution will always use distinct names from-             -- exTyvars due to the alpha-renaming pass above.-             exTyvars' = substTyVarBndrKinds subst exTyvars-             context2  = applySubstitution   subst (context1 ++ renamedContext)-             fields'   = applySubstitution   subst renamedFields-         in sequence [ ConstructorInfo name exTyvars' context2-                                       fields' stricts <$> variantQ-                     | name <- names-                     , let variantQ = getVariant name-                     ]--       _ -> fail "normalizeGadtC: Expected type constructor application"--{--Extend a type variable renaming subtitution and a list of equality-predicates by looking into kind information as much as possible.--Why is this necessary? Consider the following example:--  data (a1 :: k1) :~: (b1 :: k1) where-    Refl :: forall k2 (a2 :: k2). a2 :~: a2--After an initial call to mergeArguments, we will have the following-substitution and context:--* Substitution: [a2 :-> a1]-* Context: (a2 ~ b1)--We shouldn't stop there, however! We determine the existentially quantified-type variables of a constructor by filtering out those constructor-bound-variables which do not appear in the substitution that mergeArguments-returns. In this example, Refl's bound variables are k2 and a2. a2 appears-in the returned substitution, but k2 does not, which means that we would-mistakenly conclude that k2 is existential!--Although we don't have the full power of kind inference to guide us here, we-can at least do the next best thing. Generally, the datatype-bound type-variables and the constructor type variable binders contain all of the kind-information we need, so we proceed as follows:--1. Construct a map from each constructor-bound variable to its kind. (Do the-   same for each datatype-bound variable). These maps are the first and second-   arguments to closeOverKinds, respectively.-2. Call mergeArguments once on the GADT return type and datatype-bound types,-   and pass that in as the third argument to closeOverKinds.-3. For each name-name pair in the supplied substitution, check if the first and-   second names map to kinds in the first and second kind maps in-   closeOverKinds, respectively. If so, associate the first kind with the-   second kind.-4. For each kind association discovered in part (3), call mergeArguments-   on the lists of kinds. This will yield a kind substitution and kind-   equality context.-5. If the kind substitution is non-empty, then go back to step (3) and repeat-   the process on the new kind substitution and context.--   Otherwise, if the kind substitution is empty, then we have reached a fixed--   point (i.e., we have closed over the kinds), so proceed.-6. Union up all of the substitutions and contexts, and return those.--This algorithm is not perfect, as it will only catch everything if all of-the kinds are explicitly mentioned somewhere (and not left quantified-implicitly). Thankfully, reifying data types via Template Haskell tends to-yield a healthy amount of kind signatures, so this works quite well in-practice.--}-closeOverKinds :: Map Name Kind-               -> Map Name Kind-               -> (Map Name Name, Cxt)-               -> (Map Name Name, Cxt)-closeOverKinds domainFVKinds rangeFVKinds = go-  where-    go :: (Map Name Name, Cxt) -> (Map Name Name, Cxt)-    go (subst, context) =-      let substList = Map.toList subst-          (kindsInner, kindsOuter) =-            unzip $-            mapMaybe (\(d, r) -> do d' <- Map.lookup d domainFVKinds-                                    r' <- Map.lookup r rangeFVKinds-                                    return (d', r'))-                     substList-          (kindSubst, kindContext) = mergeArgumentKinds kindsOuter kindsInner-          (restSubst, restContext)-            = if Map.null kindSubst -- Fixed-point calculation-                 then (Map.empty, [])-                 else go (kindSubst, kindContext)-          finalSubst   = Map.unions [subst, kindSubst, restSubst]-          finalContext = nub $ concat [context, kindContext, restContext]-            -- Use `nub` here in an effort to minimize the number of-            -- redundant equality constraints in the returned context.-      in (finalSubst, finalContext)---- Look into a list of types and map each free variable name to its kind.-kindsOfFVsOfTypes :: [Type] -> Map Name Kind-kindsOfFVsOfTypes = foldMap go-  where-    go :: Type -> Map Name Kind-    go (AppT t1 t2) = go t1 `Map.union` go t2-    go (SigT t k) =-      let kSigs =-#if MIN_VERSION_template_haskell(2,8,0)-                  go k-#else-                  Map.empty-#endif-      in case t of-           VarT n -> Map.insert n k kSigs-           _      -> go t `Map.union` kSigs--    go (ForallT {})    = forallError-#if MIN_VERSION_template_haskell(2,16,0)-    go (ForallVisT {}) = forallError-#endif--    go _ = Map.empty--    forallError :: a-    forallError = error "`forall` type used in data family pattern"---- Look into a list of type variable binder and map each free variable name--- to its kind (also map the names that KindedTVs bind to their respective--- kinds). This function considers the kind of a PlainTV to be *.-kindsOfFVsOfTvbs :: [TyVarBndr_ flag] -> Map Name Kind-kindsOfFVsOfTvbs = foldMap go-  where-    go :: TyVarBndr_ flag -> Map Name Kind-    go = elimTV (\n -> Map.singleton n starK)-                (\n k -> let kSigs =-#if MIN_VERSION_template_haskell(2,8,0)-                                     kindsOfFVsOfTypes [k]-#else-                                     Map.empty-#endif-                         in Map.insert n k kSigs)--mergeArguments ::-  [Type] {- ^ outer parameters                    -} ->-  [Type] {- ^ inner parameters (specializations ) -} ->-  (Map Name Name, Cxt)-mergeArguments ns ts = foldr aux (Map.empty, []) (zip ns ts)-  where--    aux (f `AppT` x, g `AppT` y) sc =-      aux (x,y) (aux (f,g) sc)--    aux (VarT n,p) (subst, context) =-      case p of-        VarT m | m == n  -> (subst, context)-                   -- If the two variables are the same, don't bother extending-                   -- the substitution. (This is purely an optimization.)-               | Just n' <- Map.lookup m subst-               , n == n' -> (subst, context)-                   -- If a variable is already in a substitution and it maps-                   -- to the variable that we are trying to unify with, then-                   -- leave the context alone. (Not doing so caused #46.)-               | Map.notMember m subst -> (Map.insert m n subst, context)-        _ -> (subst, equalPred (VarT n) p : context)--    aux (SigT x _, y) sc = aux (x,y) sc -- learn about kinds??-    -- This matches *after* VarT so that we can compute a substitution-    -- that includes the kind signature.-    aux (x, SigT y _) sc = aux (x,y) sc--    aux _ sc = sc---- | A specialization of 'mergeArguments' to 'Kind'.--- Needed only for backwards compatibility with older versions of--- @template-haskell@.-mergeArgumentKinds ::-  [Kind] ->-  [Kind] ->-  (Map Name Name, Cxt)-#if MIN_VERSION_template_haskell(2,8,0)-mergeArgumentKinds = mergeArguments-#else-mergeArgumentKinds _ _ = (Map.empty, [])-#endif---- | Expand all of the type synonyms in a type.------ Note that this function will drop parentheses as a side effect.-resolveTypeSynonyms :: Type -> Q Type-resolveTypeSynonyms t =-  let (f, xs) = decomposeTypeArgs t-      normal_xs = filterTANormals xs--      -- Either the type is not headed by a type synonym, or it is headed by a-      -- type synonym that is not applied to enough arguments. Leave the type-      -- alone and only expand its arguments.-      defaultCase :: Type -> Q Type-      defaultCase ty = foldl appTypeArg ty <$> mapM resolveTypeArgSynonyms xs--      expandCon :: Name -- The Name to check whether it is a type synonym or not-                -> Type -- The argument type to fall back on if the supplied-                        -- Name isn't a type synonym-                -> Q Type-      expandCon n ty = do-        mbInfo <- reifyMaybe n-        case mbInfo of-          Just (TyConI (TySynD _ synvars def))-            |  length normal_xs >= length synvars -- Don't expand undersaturated type synonyms (#88)-            -> resolveTypeSynonyms $ expandSynonymRHS synvars normal_xs def-          _ -> defaultCase ty--  in case f of-       ForallT tvbs ctxt body ->-         ForallT `fmap` mapM resolve_tvb_syns tvbs-                   `ap` mapM resolvePredSynonyms ctxt-                   `ap` resolveTypeSynonyms body-       SigT ty ki -> do-         ty' <- resolveTypeSynonyms ty-         ki' <- resolveKindSynonyms ki-         defaultCase $ SigT ty' ki'-       ConT n -> expandCon n f-#if MIN_VERSION_template_haskell(2,11,0)-       InfixT t1 n t2 -> do-         t1' <- resolveTypeSynonyms t1-         t2' <- resolveTypeSynonyms t2-         expandCon n (InfixT t1' n t2')-       UInfixT t1 n t2 -> do-         t1' <- resolveTypeSynonyms t1-         t2' <- resolveTypeSynonyms t2-         expandCon n (UInfixT t1' n t2')-#endif-#if MIN_VERSION_template_haskell(2,15,0)-       ImplicitParamT n t -> do-         ImplicitParamT n <$> resolveTypeSynonyms t-#endif-#if MIN_VERSION_template_haskell(2,16,0)-       ForallVisT tvbs body ->-         ForallVisT `fmap` mapM resolve_tvb_syns tvbs-                      `ap` resolveTypeSynonyms body-#endif-#if MIN_VERSION_template_haskell(2,19,0)-       PromotedInfixT t1 n t2 -> do-         t1' <- resolveTypeSynonyms t1-         t2' <- resolveTypeSynonyms t2-         return $ PromotedInfixT t1' n t2'-       PromotedUInfixT t1 n t2 -> do-         t1' <- resolveTypeSynonyms t1-         t2' <- resolveTypeSynonyms t2-         return $ PromotedUInfixT t1' n t2'-#endif-       _ -> defaultCase f---- | Expand all of the type synonyms in a 'TypeArg'.-resolveTypeArgSynonyms :: TypeArg -> Q TypeArg-resolveTypeArgSynonyms (TANormal t) = TANormal <$> resolveTypeSynonyms t-resolveTypeArgSynonyms (TyArg k)    = TyArg    <$> resolveKindSynonyms k---- | Expand all of the type synonyms in a 'Kind'.-resolveKindSynonyms :: Kind -> Q Kind-#if MIN_VERSION_template_haskell(2,8,0)-resolveKindSynonyms = resolveTypeSynonyms-#else-resolveKindSynonyms = return -- One simply couldn't put type synonyms into-                             -- kinds on old versions of GHC.-#endif---- | Expand all of the type synonyms in a the kind of a 'TyVarBndr'.-resolve_tvb_syns :: TyVarBndr_ flag -> Q (TyVarBndr_ flag)-resolve_tvb_syns = mapMTVKind resolveKindSynonyms--expandSynonymRHS ::-  [TyVarBndr_ flag] {- ^ Substitute these variables... -} ->-  [Type]            {- ^ ...with these types... -} ->-  Type              {- ^ ...inside of this type. -} ->-  Type-expandSynonymRHS synvars ts def =-  let argNames    = map tvName synvars-      (args,rest) = splitAt (length argNames) ts-      subst       = Map.fromList (zip argNames args)-  in foldl AppT (applySubstitution subst def) rest---- | Expand all of the type synonyms in a 'Pred'.-resolvePredSynonyms :: Pred -> Q Pred-#if MIN_VERSION_template_haskell(2,10,0)-resolvePredSynonyms = resolveTypeSynonyms-#else-resolvePredSynonyms (ClassP n ts) = do-  mbInfo <- reifyMaybe n-  case mbInfo of-    Just (TyConI (TySynD _ synvars def))-      |  length ts >= length synvars -- Don't expand undersaturated type synonyms (#88)-      -> resolvePredSynonyms $ typeToPred $ expandSynonymRHS synvars ts def-    _ -> ClassP n <$> mapM resolveTypeSynonyms ts-resolvePredSynonyms (EqualP t1 t2) = do-  t1' <- resolveTypeSynonyms t1-  t2' <- resolveTypeSynonyms t2-  return (EqualP t1' t2')--typeToPred :: Type -> Pred-typeToPred t =-  let f :| xs = decomposeType t in-  case f of-    ConT n-      | n == eqTypeName-# if __GLASGOW_HASKELL__ == 704-        -- There's an unfortunate bug in GHC 7.4 where the (~) type is reified-        -- with an explicit kind argument. To work around this, we ignore it.-      , [_,t1,t2] <- xs-# else-      , [t1,t2] <- xs-# endif-      -> EqualP t1 t2-      | otherwise-      -> ClassP n xs-    _ -> error $ "typeToPred: Can't handle type " ++ show t-#endif---- | Decompose a type into a list of it's outermost applications. This process--- forgets about infix application, explicit parentheses, and visible kind--- applications.------ This operation should be used after all 'UInfixT' cases have been resolved--- by 'resolveFixities' if the argument is being user generated.------ > t ~= foldl1 AppT (decomposeType t)-decomposeType :: Type -> NonEmpty Type-decomposeType t =-  case decomposeTypeArgs t of-    (f, x) -> f :| filterTANormals x---- | A variant of 'decomposeType' that preserves information about visible kind--- applications by returning a 'NonEmpty' list of 'TypeArg's.-decomposeTypeArgs :: Type -> (Type, [TypeArg])-decomposeTypeArgs = go []-  where-    go :: [TypeArg] -> Type -> (Type, [TypeArg])-    go args (AppT f x)     = go (TANormal x:args) f-#if MIN_VERSION_template_haskell(2,11,0)-    go args (ParensT t)    = go args t-#endif-#if MIN_VERSION_template_haskell(2,15,0)-    go args (AppKindT f x) = go (TyArg x:args) f-#endif-    go args t              = (t, args)---- | An argument to a type, either a normal type ('TANormal') or a visible--- kind application ('TyArg').-data TypeArg-  = TANormal Type-  | TyArg Kind---- | Apply a 'Type' to a 'TypeArg'.-appTypeArg :: Type -> TypeArg -> Type-appTypeArg f (TANormal x) = f `AppT` x-appTypeArg f (TyArg _k) =-#if MIN_VERSION_template_haskell(2,15,0)-  f `AppKindT` _k-#else-  f -- VKA isn't supported, so conservatively drop the argument-#endif---- | Filter out all of the normal type arguments from a list of 'TypeArg's.-filterTANormals :: [TypeArg] -> [Type]-filterTANormals = mapMaybe f-  where-    f :: TypeArg -> Maybe Type-    f (TANormal t) = Just t-    f (TyArg {})   = Nothing---- 'NonEmpty' didn't move into base until recently. Reimplementing it locally--- saves dependencies for supporting older GHCs-data NonEmpty a = a :| [a]--data NonEmptySnoc a = [a] :|- a---- Decompose a function type into its context, argument types,--- and return type. For instance, this------   forall a b. (Show a, b ~ Int) => (a -> b) -> Char -> Int------ becomes------   ([a, b], [Show a, b ~ Int], [a -> b, Char] :|- Int)-uncurryType :: Type -> ([TyVarBndrSpec], Cxt, NonEmptySnoc Type)-uncurryType = go [] [] []-  where-    go tvbs ctxt args (AppT (AppT ArrowT t1) t2) = go tvbs ctxt (t1:args) t2-    go tvbs ctxt args (ForallT tvbs' ctxt' t)    = go (tvbs++tvbs') (ctxt++ctxt') args t-    go tvbs ctxt args t                          = (tvbs, ctxt, reverse args :|- t)---- | Decompose a function kind into its context, argument kinds,--- and return kind. For instance, this------  forall a b. Maybe a -> Maybe b -> Type------ becomes------   ([a, b], [], [Maybe a, Maybe b] :|- Type)-uncurryKind :: Kind -> ([TyVarBndrSpec], Cxt, NonEmptySnoc Kind)-#if MIN_VERSION_template_haskell(2,8,0)-uncurryKind = uncurryType-#else-uncurryKind = go []-  where-    go args (ArrowK k1 k2) = go (k1:args) k2-    go args StarK          = ([], [], reverse args :|- StarK)-#endif---- Reconstruct a function type from its type variable binders, context,--- argument types and return type.-curryType :: [TyVarBndrSpec] -> Cxt -> [Type] -> Type -> Type-curryType tvbs ctxt args res =-  ForallT tvbs ctxt $ foldr (\arg t -> ArrowT `AppT` arg `AppT` t) res args---- | Resolve any infix type application in a type using the fixities that--- are currently available. Starting in `template-haskell-2.11` types could--- contain unresolved infix applications.-resolveInfixT :: Type -> Q Type--#if MIN_VERSION_template_haskell(2,11,0)-resolveInfixT (ForallT vs cx t) = ForallT <$> traverse (traverseTVKind resolveInfixT) vs-                                          <*> mapM resolveInfixT cx-                                          <*> resolveInfixT t-resolveInfixT (f `AppT` x)      = resolveInfixT f `appT` resolveInfixT x-resolveInfixT (ParensT t)       = resolveInfixT t-resolveInfixT (InfixT l o r)    = conT o `appT` resolveInfixT l `appT` resolveInfixT r-resolveInfixT (SigT t k)        = SigT <$> resolveInfixT t <*> resolveInfixT k-resolveInfixT t@UInfixT{}       = resolveInfixT =<< resolveInfixT1 (gatherUInfixT t)-# if MIN_VERSION_template_haskell(2,15,0)-resolveInfixT (f `AppKindT` x)  = appKindT (resolveInfixT f) (resolveInfixT x)-resolveInfixT (ImplicitParamT n t)-                                = implicitParamT n $ resolveInfixT t-# endif-# if MIN_VERSION_template_haskell(2,16,0)-resolveInfixT (ForallVisT vs t) = ForallVisT <$> traverse (traverseTVKind resolveInfixT) vs-                                             <*> resolveInfixT t-# endif-# if MIN_VERSION_template_haskell(2,19,0)-resolveInfixT (PromotedInfixT l o r)-                                = promotedT o `appT` resolveInfixT l `appT` resolveInfixT r-resolveInfixT t@PromotedUInfixT{}-                                = resolveInfixT =<< resolveInfixT1 (gatherUInfixT t)-# endif-resolveInfixT t                 = return t--gatherUInfixT :: Type -> InfixList-gatherUInfixT (UInfixT l o r)         = ilAppend (gatherUInfixT l) o False (gatherUInfixT r)-# if MIN_VERSION_template_haskell(2,19,0)-gatherUInfixT (PromotedUInfixT l o r) = ilAppend (gatherUInfixT l) o True  (gatherUInfixT r)-# endif-gatherUInfixT t = ILNil t---- This can fail due to incompatible fixities-resolveInfixT1 :: InfixList -> TypeQ-resolveInfixT1 = go []-  where-    go :: [(Type,Name,Bool,Fixity)] -> InfixList -> TypeQ-    go ts (ILNil u) = return (foldl (\acc (l,o,p,_) -> mkConT p o `AppT` l `AppT` acc) u ts)-    go ts (ILCons l o p r) =-      do ofx <- fromMaybe defaultFixity <$> reifyFixityCompat o-         let push = go ((l,o,p,ofx):ts) r-         case ts of-           (l1,o1,p1,o1fx):ts' ->-             case compareFixity o1fx ofx of-               Just True  -> go ((mkConT p1 o1 `AppT` l1 `AppT` l, o, p, ofx):ts') r-               Just False -> push-               Nothing    -> fail (precedenceError o1 o1fx o ofx)-           _ -> push--    mkConT :: Bool -> Name -> Type-    mkConT promoted = if promoted then PromotedT else ConT--    compareFixity :: Fixity -> Fixity -> Maybe Bool-    compareFixity (Fixity n1 InfixL) (Fixity n2 InfixL) = Just (n1 >= n2)-    compareFixity (Fixity n1 InfixR) (Fixity n2 InfixR) = Just (n1 >  n2)-    compareFixity (Fixity n1 _     ) (Fixity n2 _     ) =-      case compare n1 n2 of-        GT -> Just True-        LT -> Just False-        EQ -> Nothing--    precedenceError :: Name -> Fixity -> Name -> Fixity -> String-    precedenceError o1 ofx1 o2 ofx2 =-      "Precedence parsing error: cannot mix ‘" ++-      nameBase o1 ++ "’ [" ++ showFixity ofx1 ++ "] and ‘" ++-      nameBase o2 ++ "’ [" ++ showFixity ofx2 ++-      "] in the same infix type expression"--data InfixList-  = ILCons Type      -- The first argument to the type operator-           Name      -- The name of the infix type operator-           Bool      -- 'True' if this is a promoted infix data constructor,-                     -- 'False' otherwise-           InfixList -- The rest of the infix applications to resolve-  | ILNil Type--ilAppend :: InfixList -> Name -> Bool -> InfixList -> InfixList-ilAppend (ILNil l)            o p r = ILCons l o p r-ilAppend (ILCons l1 o1 p1 r1) o p r = ILCons l1 o1 p1 (ilAppend r1 o p r)--#else--- older template-haskell packages don't have UInfixT-resolveInfixT = return-#endif----- | Render a 'Fixity' as it would appear in Haskell source.------ Example: @infixl 5@-showFixity :: Fixity -> String-showFixity (Fixity n d) = showFixityDirection d ++ " " ++ show n----- | Render a 'FixityDirection' like it would appear in Haskell source.------ Examples: @infixl@ @infixr@ @infix@-showFixityDirection :: FixityDirection -> String-showFixityDirection InfixL = "infixl"-showFixityDirection InfixR = "infixr"-showFixityDirection InfixN = "infix"--takeFieldNames :: [(Name,a,b)] -> [Name]-takeFieldNames xs = [a | (a,_,_) <- xs]--#if MIN_VERSION_template_haskell(2,11,0)-takeFieldStrictness :: [(a,Bang,b)]   -> [FieldStrictness]-#else-takeFieldStrictness :: [(a,Strict,b)] -> [FieldStrictness]-#endif-takeFieldStrictness xs = [normalizeStrictness a | (_,a,_) <- xs]--takeFieldTypes :: [(a,b,Type)] -> [Type]-takeFieldTypes xs = [a | (_,_,a) <- xs]--conHasRecord :: Name -> ConstructorInfo -> Bool-conHasRecord recName info =-  case constructorVariant info of-    NormalConstructor        -> False-    InfixConstructor         -> False-    RecordConstructor fields -> recName `elem` fields------------------------------------------------------------------------------ | Add universal quantifier for all free variables in the type. This is--- useful when constructing a type signature for a declaration.--- This code is careful to ensure that the order of the variables quantified--- is determined by their order of appearance in the type signature. (In--- contrast with being dependent upon the Ord instance for 'Name')-quantifyType :: Type -> Type-quantifyType t-  | null tvbs-  = t-  | ForallT tvbs' ctxt' t' <- t -- Collapse two consecutive foralls (#63)-  = ForallT (tvbs ++ tvbs') ctxt' t'-  | otherwise-  = ForallT tvbs [] t-  where-    tvbs = changeTVFlags SpecifiedSpec $ freeVariablesWellScoped [t]---- | Take a list of 'Type's, find their free variables, and sort them--- according to dependency order.------ As an example of how this function works, consider the following type:------ @--- Proxy (a :: k)--- @------ Calling 'freeVariables' on this type would yield @[a, k]@, since that is--- the order in which those variables appear in a left-to-right fashion. But--- this order does not preserve the fact that @k@ is the kind of @a@. Moreover,--- if you tried writing the type @forall a k. Proxy (a :: k)@, GHC would reject--- this, since GHC would demand that @k@ come before @a@.------ 'freeVariablesWellScoped' orders the free variables of a type in a way that--- preserves this dependency ordering. If one were to call--- 'freeVariablesWellScoped' on the type above, it would return--- @[k, (a :: k)]@. (This is why 'freeVariablesWellScoped' returns a list of--- 'TyVarBndr's instead of 'Name's, since it must make it explicit that @k@--- is the kind of @a@.)------ 'freeVariablesWellScoped' guarantees the free variables returned will be--- ordered such that:------ 1. Whenever an explicit kind signature of the form @(A :: K)@ is---    encountered, the free variables of @K@ will always appear to the left of---    the free variables of @A@ in the returned result.------ 2. The constraint in (1) notwithstanding, free variables will appear in---    left-to-right order of their original appearance.------ On older GHCs, this takes measures to avoid returning explicitly bound--- kind variables, which was not possible before @TypeInType@.-freeVariablesWellScoped :: [Type] -> [TyVarBndrUnit]-freeVariablesWellScoped tys =-  let fvs :: [Name]-      fvs = freeVariables tys--      varKindSigs :: Map Name Kind-      varKindSigs = foldMap go_ty tys-        where-          go_ty :: Type -> Map Name Kind-          go_ty (ForallT tvbs ctxt t) =-            foldr (\tvb -> Map.delete (tvName tvb))-                  (foldMap go_pred ctxt `mappend` go_ty t) tvbs-          go_ty (AppT t1 t2) = go_ty t1 `mappend` go_ty t2-          go_ty (SigT t k) =-            let kSigs =-#if MIN_VERSION_template_haskell(2,8,0)-                  go_ty k-#else-                  mempty-#endif-            in case t of-                 VarT n -> Map.insert n k kSigs-                 _      -> go_ty t `mappend` kSigs-#if MIN_VERSION_template_haskell(2,15,0)-          go_ty (AppKindT t k) = go_ty t `mappend` go_ty k-          go_ty (ImplicitParamT _ t) = go_ty t-#endif-#if MIN_VERSION_template_haskell(2,16,0)-          go_ty (ForallVisT tvbs t) =-            foldr (\tvb -> Map.delete (tvName tvb)) (go_ty t) tvbs-#endif-          go_ty _ = mempty--          go_pred :: Pred -> Map Name Kind-#if MIN_VERSION_template_haskell(2,10,0)-          go_pred = go_ty-#else-          go_pred (ClassP _ ts)  = foldMap go_ty ts-          go_pred (EqualP t1 t2) = go_ty t1 `mappend` go_ty t2-#endif--      -- | Do a topological sort on a list of tyvars,-      --   so that binders occur before occurrences-      -- E.g. given  [ a::k, k::*, b::k ]-      -- it'll return a well-scoped list [ k::*, a::k, b::k ]-      ---      -- This is a deterministic sorting operation-      -- (that is, doesn't depend on Uniques).-      ---      -- It is also meant to be stable: that is, variables should not-      -- be reordered unnecessarily.-      scopedSort :: [Name] -> [Name]-      scopedSort = go [] []--      go :: [Name]     -- already sorted, in reverse order-         -> [Set Name] -- each set contains all the variables which must be placed-                       -- before the tv corresponding to the set; they are accumulations-                       -- of the fvs in the sorted tvs' kinds--                       -- This list is in 1-to-1 correspondence with the sorted tyvars-                       -- INVARIANT:-                       --   all (\tl -> all (`isSubsetOf` head tl) (tail tl)) (tails fv_list)-                       -- That is, each set in the list is a superset of all later sets.-         -> [Name]     -- yet to be sorted-         -> [Name]-      go acc _fv_list [] = reverse acc-      go acc  fv_list (tv:tvs)-        = go acc' fv_list' tvs-        where-          (acc', fv_list') = insert tv acc fv_list--      insert :: Name       -- var to insert-             -> [Name]     -- sorted list, in reverse order-             -> [Set Name] -- list of fvs, as above-             -> ([Name], [Set Name])   -- augmented lists-      insert tv []     []         = ([tv], [kindFVSet tv])-      insert tv (a:as) (fvs:fvss)-        | tv `Set.member` fvs-        , (as', fvss') <- insert tv as fvss-        = (a:as', fvs `Set.union` fv_tv : fvss')--        | otherwise-        = (tv:a:as, fvs `Set.union` fv_tv : fvs : fvss)-        where-          fv_tv = kindFVSet tv--         -- lists not in correspondence-      insert _ _ _ = error "scopedSort"--      kindFVSet n =-        maybe Set.empty (Set.fromList . freeVariables) (Map.lookup n varKindSigs)-      ascribeWithKind n =-        maybe (plainTV n) (kindedTV n) (Map.lookup n varKindSigs)--      -- An annoying wrinkle: GHCs before 8.0 don't support explicitly-      -- quantifying kinds, so something like @forall k (a :: k)@ would be-      -- rejected. To work around this, we filter out any binders whose names-      -- also appear in a kind on old GHCs.-      isKindBinderOnOldGHCs-#if __GLASGOW_HASKELL__ >= 800-        = const False-#else-        = (`elem` kindVars)-          where-            kindVars = freeVariables $ Map.elems varKindSigs-#endif--  in map ascribeWithKind $-     filter (not . isKindBinderOnOldGHCs) $-     scopedSort fvs---- | Substitute all of the free variables in a type with fresh ones-freshenFreeVariables :: Type -> Q Type-freshenFreeVariables t =-  do let xs = [ (n, VarT <$> newName (nameBase n)) | n <- freeVariables t]-     subst <- T.sequence (Map.fromList xs)-     return (applySubstitution subst t)----- | Class for types that support type variable substitution.-class TypeSubstitution a where-  -- | Apply a type variable substitution.-  applySubstitution :: Map Name Type -> a -> a-  -- | Compute the free type variables-  freeVariables     :: a -> [Name]--instance TypeSubstitution a => TypeSubstitution [a] where-  freeVariables     = nub . concat . map freeVariables-  applySubstitution = fmap . applySubstitution--instance TypeSubstitution Type where-  applySubstitution subst = go-    where-      go (ForallT tvs context t) =-        let (subst', tvs') = substTyVarBndrs subst tvs in-        ForallT tvs'-                (applySubstitution subst' context)-                (applySubstitution subst' t)-      go (AppT f x)      = AppT (go f) (go x)-      go (SigT t k)      = SigT (go t) (applySubstitution subst k) -- k could be Kind-      go (VarT v)        = Map.findWithDefault (VarT v) v subst-#if MIN_VERSION_template_haskell(2,11,0)-      go (InfixT l c r)  = InfixT (go l) c (go r)-      go (UInfixT l c r) = UInfixT (go l) c (go r)-      go (ParensT t)     = ParensT (go t)-#endif-#if MIN_VERSION_template_haskell(2,15,0)-      go (AppKindT t k)  = AppKindT (go t) (go k)-      go (ImplicitParamT n t)-                         = ImplicitParamT n (go t)-#endif-#if MIN_VERSION_template_haskell(2,16,0)-      go (ForallVisT tvs t) =-        let (subst', tvs') = substTyVarBndrs subst tvs in-        ForallVisT tvs'-                   (applySubstitution subst' t)-#endif-#if MIN_VERSION_template_haskell(2,19,0)-      go (PromotedInfixT l c r)-                         = PromotedInfixT (go l) c (go r)-      go (PromotedUInfixT l c r)-                         = PromotedUInfixT (go l) c (go r)-#endif-      go t               = t--      subst_tvbs :: [TyVarBndr_ flag] -> (Map Name Type -> a) -> a-      subst_tvbs tvs k = k $ foldl' (flip Map.delete) subst (map tvName tvs)--  freeVariables t =-    case t of-      ForallT tvs context t' ->-          fvs_under_forall tvs (freeVariables context `union` freeVariables t')-      AppT f x      -> freeVariables f `union` freeVariables x-      SigT t' k     -> freeVariables t' `union` freeVariables k-      VarT v        -> [v]-#if MIN_VERSION_template_haskell(2,11,0)-      InfixT l _ r  -> freeVariables l `union` freeVariables r-      UInfixT l _ r -> freeVariables l `union` freeVariables r-      ParensT t'    -> freeVariables t'-#endif-#if MIN_VERSION_template_haskell(2,15,0)-      AppKindT t k  -> freeVariables t `union` freeVariables k-      ImplicitParamT _ t-                    -> freeVariables t-#endif-#if MIN_VERSION_template_haskell(2,16,0)-      ForallVisT tvs t'-                    -> fvs_under_forall tvs (freeVariables t')-#endif-#if MIN_VERSION_template_haskell(2,19,0)-      PromotedInfixT l _ r-                    -> freeVariables l `union` freeVariables r-      PromotedUInfixT l _ r-                    -> freeVariables l `union` freeVariables r-#endif-      _             -> []-    where-      fvs_under_forall :: [TyVarBndr_ flag] -> [Name] -> [Name]-      fvs_under_forall tvs fvs =-        (freeVariables (map tvKind tvs) `union` fvs)-        \\ map tvName tvs--instance TypeSubstitution ConstructorInfo where-  freeVariables ci =-      (freeVariables (map tvKind (constructorVars ci))-          `union` freeVariables (constructorContext ci)-          `union` freeVariables (constructorFields ci))-      \\ (tvName <$> constructorVars ci)--  applySubstitution subst ci =-    let subst' = foldl' (flip Map.delete) subst (map tvName (constructorVars ci)) in-    ci { constructorVars    = map (mapTVKind (applySubstitution subst'))-                                  (constructorVars ci)-       , constructorContext = applySubstitution subst' (constructorContext ci)-       , constructorFields  = applySubstitution subst' (constructorFields ci)-       }---- 'Pred' became a type synonym for 'Type'-#if !MIN_VERSION_template_haskell(2,10,0)-instance TypeSubstitution Pred where-  freeVariables (ClassP _ xs) = freeVariables xs-  freeVariables (EqualP x y) = freeVariables x `union` freeVariables y--  applySubstitution p (ClassP n xs) = ClassP n (applySubstitution p xs)-  applySubstitution p (EqualP x y) = EqualP (applySubstitution p x)-                                            (applySubstitution p y)-#endif---- 'Kind' became a type synonym for 'Type'. Previously there were no kind variables-#if !MIN_VERSION_template_haskell(2,8,0)-instance TypeSubstitution Kind where-  freeVariables _ = []-  applySubstitution _ k = k-#endif---- | Substitutes into the kinds of type variable binders. This makes an effort--- to avoid capturing the 'TyVarBndr' names during substitution by--- alpha-renaming names if absolutely necessary. For a version of this function--- which does /not/ avoid capture, see 'substTyVarBndrKinds'.-substTyVarBndrs :: Map Name Type -> [TyVarBndr_ flag] -> (Map Name Type, [TyVarBndr_ flag])-substTyVarBndrs = mapAccumL substTyVarBndr---- | The workhorse for 'substTyVarBndrs'.-substTyVarBndr :: Map Name Type -> TyVarBndr_ flag -> (Map Name Type, TyVarBndr_ flag)-substTyVarBndr subst tvb-  | tvbName `Map.member` subst-  = (Map.delete tvbName subst, mapTVKind (applySubstitution subst) tvb)-  | tvbName `Set.notMember` substRangeFVs-  = (subst, mapTVKind (applySubstitution subst) tvb)-  | otherwise-  = let tvbName' = evade tvbName in-    ( Map.insert tvbName (VarT tvbName') subst-    , mapTV (\_ -> tvbName') id (applySubstitution subst) tvb-    )-  where-    tvbName :: Name-    tvbName = tvName tvb--    substRangeFVs :: Set Name-    substRangeFVs = Set.fromList $ freeVariables $ Map.elems subst--    evade :: Name -> Name-    evade n | n `Set.member` substRangeFVs-            = evade $ bump n-            | otherwise-            = n--    -- An improvement would be to try a variety of different characters instead-    -- of prepending the same character repeatedly. Let's wait to see if-    -- someone complains about this before making this more complicated,-    -- however.-    bump :: Name -> Name-    bump n = mkName $ 'f':nameBase n---- | Substitutes into the kinds of type variable binders. This is slightly more--- efficient than 'substTyVarBndrs', but at the expense of not avoiding--- capture. Only use this function in situations where you know that none of--- the 'TyVarBndr' names are contained in the range of the substitution.-substTyVarBndrKinds :: Map Name Type -> [TyVarBndr_ flag] -> [TyVarBndr_ flag]-substTyVarBndrKinds subst = map (substTyVarBndrKind subst)---- | The workhorse for 'substTyVarBndrKinds'.-substTyVarBndrKind :: Map Name Type -> TyVarBndr_ flag -> TyVarBndr_ flag-substTyVarBndrKind subst = mapTVKind (applySubstitution subst)----------------------------------------------------------------------------combineSubstitutions :: Map Name Type -> Map Name Type -> Map Name Type-combineSubstitutions x y = Map.union (fmap (applySubstitution y) x) y---- | Compute the type variable substitution that unifies a list of types,--- or fail in 'Q'.------ All infix issue should be resolved before using 'unifyTypes'------ Alpha equivalent quantified types are not unified.-unifyTypes :: [Type] -> Q (Map Name Type)-unifyTypes [] = return Map.empty-unifyTypes (t:ts) =-  do t':ts' <- mapM resolveTypeSynonyms (t:ts)-     let aux sub u =-           do sub' <- unify' (applySubstitution sub t')-                             (applySubstitution sub u)-              return (combineSubstitutions sub sub')--     case foldM aux Map.empty ts' of-       Right m -> return m-       Left (x,y) ->-         fail $ showString "Unable to unify types "-              . showsPrec 11 x-              . showString " and "-              . showsPrec 11 y-              $ ""--unify' :: Type -> Type -> Either (Type,Type) (Map Name Type)--unify' (VarT n) (VarT m) | n == m = pure Map.empty-unify' (VarT n) t | n `elem` freeVariables t = Left (VarT n, t)-                  | otherwise                = Right (Map.singleton n t)-unify' t (VarT n) | n `elem` freeVariables t = Left (VarT n, t)-                  | otherwise                = Right (Map.singleton n t)--unify' (AppT f1 x1) (AppT f2 x2) =-  do sub1 <- unify' f1 f2-     sub2 <- unify' (applySubstitution sub1 x1) (applySubstitution sub1 x2)-     Right (combineSubstitutions sub1 sub2)---- Doesn't unify kind signatures-unify' (SigT t _) u = unify' t u-unify' t (SigT u _) = unify' t u---- only non-recursive cases should remain at this point-unify' t u-  | t == u    = Right Map.empty-  | otherwise = Left (t,u)----- | Construct an equality constraint. The implementation of 'Pred' varies--- across versions of Template Haskell.-equalPred :: Type -> Type -> Pred-equalPred x y =-#if MIN_VERSION_template_haskell(2,10,0)-  AppT (AppT EqualityT x) y-#else-  EqualP x y-#endif---- | Construct a typeclass constraint. The implementation of 'Pred' varies--- across versions of Template Haskell.-classPred :: Name {- ^ class -} -> [Type] {- ^ parameters -} -> Pred-classPred =-#if MIN_VERSION_template_haskell(2,10,0)-  foldl AppT . ConT-#else-  ClassP-#endif---- | Match a 'Pred' representing an equality constraint. Returns--- arguments to the equality constraint if successful.-asEqualPred :: Pred -> Maybe (Type,Type)-#if MIN_VERSION_template_haskell(2,10,0)-asEqualPred (EqualityT `AppT` x `AppT` y)                    = Just (x,y)-asEqualPred (ConT eq   `AppT` x `AppT` y) | eq == eqTypeName = Just (x,y)-#else-asEqualPred (EqualP            x        y)                   = Just (x,y)-#endif-asEqualPred _                                                = Nothing---- | Match a 'Pred' representing a class constraint.--- Returns the classname and parameters if successful.-asClassPred :: Pred -> Maybe (Name, [Type])-#if MIN_VERSION_template_haskell(2,10,0)-asClassPred t =-  case decomposeType t of-    ConT f :| xs | f /= eqTypeName -> Just (f,xs)-    _                              -> Nothing-#else-asClassPred (ClassP f xs) = Just (f,xs)-asClassPred _             = Nothing-#endif------------------------------------------------------------------------------ | If we are working with a 'Dec' obtained via 'reify' (as opposed to one--- created from, say, [d| ... |] quotes), then we need to apply more hacks than--- we otherwise would to sanitize the 'Dec'. See #28.-type IsReifiedDec = Bool--isReified, isn'tReified :: IsReifiedDec-isReified    = True-isn'tReified = False---- On old versions of GHC, reify would not give you kind signatures for--- GADT type variables of kind *. To work around this, we insert the kinds--- manually on any reified type variable binders without a signature. However,--- don't do this for quoted type variable binders (#84).--giveDIVarsStarKinds :: IsReifiedDec -> DatatypeInfo -> DatatypeInfo-giveDIVarsStarKinds isReified info =-  info { datatypeVars      = map (giveTyVarBndrStarKind isReified) (datatypeVars info)-       , datatypeInstTypes = map (giveTypeStarKind isReified) (datatypeInstTypes info) }--giveCIVarsStarKinds :: IsReifiedDec -> ConstructorInfo -> ConstructorInfo-giveCIVarsStarKinds isReified info =-  info { constructorVars = map (giveTyVarBndrStarKind isReified) (constructorVars info) }--giveTyVarBndrStarKind :: IsReifiedDec ->  TyVarBndrUnit -> TyVarBndrUnit-giveTyVarBndrStarKind isReified tvb-  | isReified-  = elimTV (\n -> kindedTV n starK) (\_ _ -> tvb) tvb-  | otherwise-  = tvb--giveTypeStarKind :: IsReifiedDec -> Type -> Type-giveTypeStarKind isReified t-  | isReified-  = case t of-      VarT n -> SigT t starK-      _      -> t-  | otherwise-  = t---- | Prior to GHC 8.2.1, reify was broken for data instances and newtype--- instances. This code attempts to detect the problem and repair it if--- possible.------ The particular problem is that the type variables used in the patterns--- while defining a data family instance do not completely match those--- used when defining the fields of the value constructors beyond the--- base names. This code attempts to recover the relationship between the--- type variables.------ It is possible, however, to generate these kinds of declarations by--- means other than reify. In these cases the name bases might not be--- unique and the declarations might be well formed. In such a case this--- code attempts to avoid altering the declaration.------ https://ghc.haskell.org/trac/ghc/ticket/13618-repair13618 :: DatatypeInfo -> Q DatatypeInfo-repair13618 info =-  do s <- T.sequence (Map.fromList substList)-     return info { datatypeCons = applySubstitution s (datatypeCons info) }--  where-    used  = freeVariables (datatypeCons info)-    bound = map tvName (datatypeVars info)-    free  = used \\ bound--    substList =-      [ (u, substEntry u vs)-      | u <- free-      , let vs = [v | v <- bound, nameBase v == nameBase u]-      ]--    substEntry _ [v] = varT v-    substEntry u []  = fail ("Impossible free variable: " ++ show u)-    substEntry u _   = fail ("Ambiguous free variable: "  ++ show u)------------------------------------------------------------------------------ | Backward compatible version of 'dataD'-dataDCompat ::-  CxtQ            {- ^ context                 -} ->-  Name            {- ^ type constructor        -} ->-  [TyVarBndrUnit] {- ^ type parameters         -} ->-  [ConQ]          {- ^ constructor definitions -} ->-  [Name]          {- ^ derived class names     -} ->-  DecQ-#if MIN_VERSION_template_haskell(2,12,0)-dataDCompat c n ts cs ds =-  dataD c n ts Nothing cs-    (if null ds then [] else [derivClause Nothing (map conT ds)])-#elif MIN_VERSION_template_haskell(2,11,0)-dataDCompat c n ts cs ds =-  dataD c n ts Nothing cs-    (return (map ConT ds))-#else-dataDCompat = dataD-#endif---- | Backward compatible version of 'newtypeD'-newtypeDCompat ::-  CxtQ            {- ^ context                 -} ->-  Name            {- ^ type constructor        -} ->-  [TyVarBndrUnit] {- ^ type parameters         -} ->-  ConQ            {- ^ constructor definition  -} ->-  [Name]          {- ^ derived class names     -} ->-  DecQ-#if MIN_VERSION_template_haskell(2,12,0)-newtypeDCompat c n ts cs ds =-  newtypeD c n ts Nothing cs-    (if null ds then [] else [derivClause Nothing (map conT ds)])-#elif MIN_VERSION_template_haskell(2,11,0)-newtypeDCompat c n ts cs ds =-  newtypeD c n ts Nothing cs-    (return (map ConT ds))-#else-newtypeDCompat = newtypeD-#endif---- | Backward compatible version of 'tySynInstD'-tySynInstDCompat ::-  Name                    {- ^ type family name    -}   ->-  Maybe [Q TyVarBndrUnit] {- ^ type variable binders -} ->-  [TypeQ]                 {- ^ instance parameters -}   ->-  TypeQ                   {- ^ instance result     -}   ->-  DecQ-#if MIN_VERSION_template_haskell(2,15,0)-tySynInstDCompat n mtvbs ps r = TySynInstD <$> (TySynEqn <$> mapM sequence mtvbs-                                                         <*> foldl' appT (conT n) ps-                                                         <*> r)-#elif MIN_VERSION_template_haskell(2,9,0)-tySynInstDCompat n _ ps r     = TySynInstD n <$> (TySynEqn <$> sequence ps <*> r)-#else-tySynInstDCompat n _          = tySynInstD n-#endif---- | Backward compatible version of 'pragLineD'. Returns--- 'Nothing' if line pragmas are not suported.-pragLineDCompat ::-  Int     {- ^ line number -} ->-  String  {- ^ file name   -} ->-  Maybe DecQ-#if MIN_VERSION_template_haskell(2,10,0)-pragLineDCompat ln fn = Just (pragLineD ln fn)-#else-pragLineDCompat _  _  = Nothing-#endif--arrowKCompat :: Kind -> Kind -> Kind-#if MIN_VERSION_template_haskell(2,8,0)-arrowKCompat x y = arrowK `appK` x `appK` y-#else-arrowKCompat = arrowK-#endif------------------------------------------------------------------------------ | Backwards compatibility wrapper for 'Fixity' lookup.------ In @template-haskell-2.11.0.0@ and later, the answer will always--- be 'Just' of a fixity.------ Before @template-haskell-2.11.0.0@ it was only possible to determine--- fixity information for variables, class methods, and data constructors.--- In this case for type operators the answer could be 'Nothing', which--- indicates that the answer is unavailable.-reifyFixityCompat :: Name -> Q (Maybe Fixity)-#if MIN_VERSION_template_haskell(2,11,0)-reifyFixityCompat n = recover (return Nothing) ((`mplus` Just defaultFixity) <$> reifyFixity n)-#else-reifyFixityCompat n = recover (return Nothing) $-  do info <- reify n-     return $! case info of-       ClassOpI _ _ _ fixity -> Just fixity-       DataConI _ _ _ fixity -> Just fixity-       VarI     _ _ _ fixity -> Just fixity-       _                     -> Nothing-#endif+{-# Language CPP, DeriveDataTypeable, DeriveGeneric, ScopedTypeVariables, TupleSections #-}++#if MIN_VERSION_template_haskell(2,12,0)+{-# Language Safe #-}+#else+{-# Language Trustworthy #-}+#endif++{-|+Module      : Language.Haskell.TH.Datatype+Description : Backwards-compatible interface to reified information about datatypes.+Copyright   : Eric Mertens 2017-2020+License     : ISC+Maintainer  : emertens@gmail.com++This module provides a flattened view of information about data types+and newtypes that can be supported uniformly across multiple versions+of the @template-haskell@ package.++Sample output for @'reifyDatatype' ''Maybe@++@+'DatatypeInfo'+ { 'datatypeContext'   = []+ , 'datatypeName'      = GHC.Base.Maybe+ , 'datatypeVars'      = [ 'KindedTV' a_3530822107858468866 () 'StarT' ]+ , 'datatypeInstTypes' = [ 'SigT' ('VarT' a_3530822107858468866) 'StarT' ]+ , 'datatypeVariant'   = 'Datatype'+ , 'datatypeReturnKind' = 'StarT'+ , 'datatypeCons'      =+     [ 'ConstructorInfo'+         { 'constructorName'       = GHC.Base.Nothing+         , 'constructorVars'       = []+         , 'constructorContext'    = []+         , 'constructorFields'     = []+         , 'constructorStrictness' = []+         , 'constructorVariant'    = 'NormalConstructor'+         }+     , 'ConstructorInfo'+         { 'constructorName'       = GHC.Base.Just+         , 'constructorVars'       = []+         , 'constructorContext'    = []+         , 'constructorFields'     = [ 'VarT' a_3530822107858468866 ]+         , 'constructorStrictness' = [ 'FieldStrictness'+                                         'UnspecifiedUnpackedness'+                                         'Lazy'+                                     ]+         , 'constructorVariant'    = 'NormalConstructor'+         }+     ]+ }+@++Datatypes declared with GADT syntax are normalized to constructors with existentially+quantified type variables and equality constraints.++-}+module Language.Haskell.TH.Datatype+  (+  -- * Types+    DatatypeInfo(..)+  , ConstructorInfo(..)+  , DatatypeVariant(..)+  , ConstructorVariant(..)+  , FieldStrictness(..)+  , Unpackedness(..)+  , Strictness(..)++  -- * Normalization functions+  , reifyDatatype+  , reifyConstructor+  , reifyRecord+  , normalizeInfo+  , normalizeDec+  , normalizeCon++  -- * 'DatatypeInfo' lookup functions+  , lookupByConstructorName+  , lookupByRecordName++  -- * Type variable manipulation+  , TypeSubstitution(..)+  , quantifyType+  , freeVariablesWellScoped+  , freshenFreeVariables++  -- * 'Pred' functions+  , equalPred+  , classPred+  , asEqualPred+  , asClassPred++  -- * Backward compatible data definitions+  , dataDCompat+  , newtypeDCompat+  , tySynInstDCompat+  , pragLineDCompat+  , arrowKCompat++  -- * Strictness annotations+  , isStrictAnnot+  , notStrictAnnot+  , unpackedAnnot++  -- * Type simplification+  , resolveTypeSynonyms+  , resolveKindSynonyms+  , resolvePredSynonyms+  , resolveInfixT++  -- * Fixities+  , reifyFixityCompat+  , showFixity+  , showFixityDirection++  -- * Convenience functions+  , unifyTypes+  , tvName+  , tvKind+  , datatypeType+  ) where++import           Control.Monad+import           Data.Data (Data)+import           Data.Foldable (foldMap, foldl')+import           Data.List (mapAccumL, nub, find, union, (\\))+import           Data.Map (Map)+import qualified Data.Map as Map+import           Data.Maybe+import qualified Data.Set as Set+import           Data.Set (Set)+import qualified Data.Traversable as T+import           GHC.Generics (Generic)+import           Language.Haskell.TH hiding (Extension(..))+import           Language.Haskell.TH.Datatype.Internal+import           Language.Haskell.TH.Datatype.TyVarBndr+import           Language.Haskell.TH.Lib (arrowK, starK) -- needed for th-2.4++-- | Normalized information about newtypes and data types.+--+-- 'DatatypeInfo' contains two fields, 'datatypeVars' and 'datatypeInstTypes',+-- which encode information about the argument types. The simplest explanation+-- is that 'datatypeVars' contains all the type /variables/ bound by the data+-- type constructor, while 'datatypeInstTypes' contains the type /arguments/+-- to the data type constructor. To be more precise:+--+-- * For ADTs declared with @data@ and @newtype@, it will likely be the case+--   that 'datatypeVars' and 'datatypeInstTypes' coincide. For instance, given+--   @newtype Id a = MkId a@, in the 'DatatypeInfo' for @Id@ we would+--   have @'datatypeVars' = ['KindedTV' a () 'StarT']@ and+--   @'datatypeInstVars' = ['SigT' ('VarT' a) 'StarT']@.+--+--   ADTs that leverage @PolyKinds@ may have more 'datatypeVars' than+--   'datatypeInstTypes'. For instance, given @data Proxy (a :: k) = MkProxy@,+--   in the 'DatatypeInfo' for @Proxy@ we would have+--   @'datatypeVars' = ['KindedTV' k () 'StarT', 'KindedTV' a () ('VarT' k)]@+--   (since there are two variables, @k@ and @a@), whereas+--   @'datatypeInstTypes' = ['SigT' ('VarT' a) ('VarT' k)]@, since there is+--   only one explicit type argument to @Proxy@.+--+--   The same outcome would occur if @Proxy@ were declared using+--   @TypeAbstractions@, i.e., if it were declared as+--   @data Proxy \@k (a :: k) = MkProxy@. The 'datatypeInstTypes' would /not/+--   include a separate type for @\@k@.+--+-- * For @data instance@s and @newtype instance@s of data families,+--   'datatypeVars' and 'datatypeInstTypes' can be quite different. Here is+--   an example to illustrate the difference:+--+--   @+--   data family F a b+--   data instance F (Maybe c) (f x) = MkF c (f x)+--   @+--+--   Then in the 'DatatypeInfo' for @F@'s data instance, we would have:+--+--   @+--   'datatypeVars'      = [ 'KindedTV' c () 'StarT'+--                         , 'KindedTV' f () 'StarT'+--                         , 'KindedTV' x () 'StarT' ]+--   'datatypeInstTypes' = [ 'AppT' ('ConT' ''Maybe) ('VarT' c)+--                         , 'AppT' ('VarT' f) ('VarT' x) ]+--   @+data DatatypeInfo = DatatypeInfo+  { datatypeContext   :: Cxt               -- ^ Data type context (deprecated)+  , datatypeName      :: Name              -- ^ Type constructor+  , datatypeVars      :: [TyVarBndrUnit]   -- ^ Type parameters+  , datatypeInstTypes :: [Type]            -- ^ Argument types+  , datatypeVariant   :: DatatypeVariant   -- ^ Extra information+  , datatypeReturnKind:: Kind              -- ^ Return 'Kind' of the type.+                                           --+                                           -- If normalization is unable to determine the return kind,+                                           -- then this is conservatively set to @StarT@.+  , datatypeCons      :: [ConstructorInfo] -- ^ Normalize constructor information+  }+  deriving (Show, Eq, Data, Generic)++-- | Possible variants of data type declarations.+data DatatypeVariant+  = Datatype        -- ^ Type declared with @data@ or a primitive datatype.+  | Newtype         -- ^ Type declared with @newtype@.+                    --+                    --   A 'DatatypeInfo' that uses 'Newtype' will uphold the+                    --   invariant that there will be exactly one+                    --   'ConstructorInfo' in the 'datatypeCons'.+  | DataInstance    -- ^ Type declared with @data instance@.+  | NewtypeInstance -- ^ Type declared with @newtype instance@.+                    --+                    --   A 'DatatypeInfo' that uses 'NewtypeInstance' will+                    --   uphold the invariant that there will be exactly one+                    --   'ConstructorInfo' in the 'datatypeCons'.+  | TypeData        -- ^ Type declared with @type data@.+                    --+                    --   A 'DatatypeInfo' that uses 'TypeData' will uphold the+                    --   following invariants:+                    --+                    --   * The 'datatypeContext' will be empty.+                    --+                    --   * None of the 'constructorVariant's in any of the+                    --     'datatypeCons' will be 'RecordConstructor'.+                    --+                    --   * Each of the 'constructorStrictness' values in each+                    --     of the 'datatypeCons' will be equal to+                    --     'notStrictAnnot'.+  deriving (Show, Read, Eq, Ord, Data, Generic)++-- | Normalized information about constructors associated with newtypes and+-- data types.+data ConstructorInfo = ConstructorInfo+  { constructorName       :: Name               -- ^ Constructor name+  , constructorVars       :: [TyVarBndrUnit]    -- ^ Constructor type parameters+  , constructorContext    :: Cxt                -- ^ Constructor constraints+  , constructorFields     :: [Type]             -- ^ Constructor fields+  , constructorStrictness :: [FieldStrictness]  -- ^ Constructor fields' strictness+                                                --   (Invariant: has the same length+                                                --   as constructorFields)+  , constructorVariant    :: ConstructorVariant -- ^ Extra information+  }+  deriving (Show, Eq, Data, Generic)++-- | Possible variants of data constructors.+data ConstructorVariant+  = NormalConstructor        -- ^ Constructor without field names+  | InfixConstructor         -- ^ Constructor without field names that is+                             --   declared infix+  | RecordConstructor [Name] -- ^ Constructor with field names+  deriving (Show, Eq, Ord, Data, Generic)++-- | Normalized information about a constructor field's @UNPACK@ and+-- strictness annotations.+--+-- Note that the interface for reifying strictness in Template Haskell changed+-- considerably in GHC 8.0. The presentation in this library mirrors that which+-- can be found in GHC 8.0 or later, whereas previously, unpackedness and+-- strictness were represented with a single data type:+--+-- @+-- data Strict+--   = IsStrict+--   | NotStrict+--   | Unpacked -- On GHC 7.4 or later+-- @+--+-- For backwards compatibility, we retrofit these constructors onto the+-- following three values, respectively:+--+-- @+-- 'isStrictAnnot'  = 'FieldStrictness' 'UnspecifiedUnpackedness' 'Strict'+-- 'notStrictAnnot' = 'FieldStrictness' 'UnspecifiedUnpackedness' 'UnspecifiedStrictness'+-- 'unpackedAnnot'  = 'FieldStrictness' 'Unpack' 'Strict'+-- @+data FieldStrictness = FieldStrictness+  { fieldUnpackedness :: Unpackedness+  , fieldStrictness   :: Strictness+  }+  deriving (Show, Eq, Ord, Data, Generic)++-- | Information about a constructor field's unpackedness annotation.+data Unpackedness+  = UnspecifiedUnpackedness -- ^ No annotation whatsoever+  | NoUnpack                -- ^ Annotated with @{\-\# NOUNPACK \#-\}@+  | Unpack                  -- ^ Annotated with @{\-\# UNPACK \#-\}@+  deriving (Show, Eq, Ord, Data, Generic)++-- | Information about a constructor field's strictness annotation.+data Strictness+  = UnspecifiedStrictness -- ^ No annotation whatsoever+  | Lazy                  -- ^ Annotated with @~@+  | Strict                -- ^ Annotated with @!@+  deriving (Show, Eq, Ord, Data, Generic)++isStrictAnnot, notStrictAnnot, unpackedAnnot :: FieldStrictness+isStrictAnnot  = FieldStrictness UnspecifiedUnpackedness Strict+notStrictAnnot = FieldStrictness UnspecifiedUnpackedness UnspecifiedStrictness+unpackedAnnot  = FieldStrictness Unpack Strict++-- | Construct a Type using the datatype's type constructor and type+-- parameters. Kind signatures are removed.+datatypeType :: DatatypeInfo -> Type+datatypeType di+  = foldl AppT (ConT (datatypeName di))+  $ map stripSigT+  $ datatypeInstTypes di+++-- | Compute a normalized view of the metadata about a data type or newtype+-- given a constructor.+--+-- This function will accept any constructor (value or type) for a type+-- declared with newtype or data. Value constructors must be used to+-- lookup datatype information about /data instances/ and /newtype instances/,+-- as giving the type constructor of a data family is often not enough to+-- determine a particular data family instance.+--+-- In addition, this function will also accept a record selector for a+-- data type with a constructor which uses that record.+--+-- GADT constructors are normalized into datatypes with explicit equality+-- constraints. Note that no effort is made to distinguish between equalities of+-- the same (homogeneous) kind and equalities between different (heterogeneous)+-- kinds. For instance, the following GADT's constructors:+--+-- @+-- data T (a :: k -> *) where+--   MkT1 :: T Proxy+--   MkT2 :: T Maybe+-- @+--+-- will be normalized to the following equality constraints:+--+-- @+-- AppT (AppT EqualityT (VarT a)) (ConT Proxy) -- MkT1+-- AppT (AppT EqualityT (VarT a)) (ConT Maybe) -- MkT2+-- @+--+-- But only the first equality constraint is well kinded, since in the second+-- constraint, the kinds of @(a :: k -> *)@ and @(Maybe :: * -> *)@ are different.+-- Trying to categorize which constraints need homogeneous or heterogeneous+-- equality is tricky, so we leave that task to users of this library.+--+-- Primitive types (other than unboxed sums and tuples) will have+-- no @datatypeCons@ in their normalization.+--+-- This function will apply various bug-fixes to the output of the underlying+-- @template-haskell@ library in order to provide a view of datatypes in+-- as uniform a way as possible.+reifyDatatype ::+  Name {- ^ data type or constructor name -} ->+  Q DatatypeInfo+reifyDatatype n = normalizeInfo' "reifyDatatype" isReified =<< reify n++-- | Compute a normalized view of the metadata about a constructor given its+-- 'Name'. This is useful for scenarios when you don't care about the info for+-- the enclosing data type.+reifyConstructor ::+  Name {- ^ constructor name -} ->+  Q ConstructorInfo+reifyConstructor conName = do+  dataInfo <- reifyDatatype conName+  return $ lookupByConstructorName conName dataInfo++-- | Compute a normalized view of the metadata about a constructor given the+-- 'Name' of one of its record selectors. This is useful for scenarios when you+-- don't care about the info for the enclosing data type.+reifyRecord ::+  Name {- ^ record name -} ->+  Q ConstructorInfo+reifyRecord recordName = do+  dataInfo <- reifyDatatype recordName+  return $ lookupByRecordName recordName dataInfo++-- | Given a 'DatatypeInfo', find the 'ConstructorInfo' corresponding to the+-- 'Name' of one of its constructors.+lookupByConstructorName ::+  Name {- ^ constructor name -} ->+  DatatypeInfo {- ^ info for the datatype which has that constructor -} ->+  ConstructorInfo+lookupByConstructorName conName dataInfo =+  case find ((== conName) . constructorName) (datatypeCons dataInfo) of+    Just conInfo -> conInfo+    Nothing      -> error $ "Datatype " ++ nameBase (datatypeName dataInfo)+                         ++ " does not have a constructor named " ++ nameBase conName+-- | Given a 'DatatypeInfo', find the 'ConstructorInfo' corresponding to the+-- 'Name' of one of its constructors.+lookupByRecordName ::+  Name {- ^ record name -} ->+  DatatypeInfo {- ^ info for the datatype which has that constructor -} ->+  ConstructorInfo+lookupByRecordName recordName dataInfo =+  case find (conHasRecord recordName) (datatypeCons dataInfo) of+    Just conInfo -> conInfo+    Nothing      -> error $ "Datatype " ++ nameBase (datatypeName dataInfo)+                         ++ " does not have any constructors with a "+                         ++ "record selector named " ++ nameBase recordName++-- | Normalize 'Info' for a newtype or datatype into a 'DatatypeInfo'.+-- Fail in 'Q' otherwise.+normalizeInfo :: Info -> Q DatatypeInfo+normalizeInfo = normalizeInfo' "normalizeInfo" isn'tReified++normalizeInfo' :: String -> IsReifiedDec -> Info -> Q DatatypeInfo+normalizeInfo' entry reifiedDec i =+  case i of+    (PrimTyConI name arity unlifted) -> do+#if MIN_VERSION_template_haskell(2,16,0)+      -- We provide a minimal @DataD@ because, since TH 2.16,+      -- we can rely on the call to @reifyType@ in+      -- @normalizeDecFor@ to fill in the missing details.+      normalizeDecFor reifiedDec $ DataD [] name [] Nothing [] []+#else+      -- On older versions, we are very limited in what we can deduce.+      -- All we know is the appropriate amount of type constructors.+      -- Note that this will default all kinds to @Type@, which is all+      -- that is available anyway.+      args <- replicateM arity (newName "x")+      dec <- dataDCompat (return []) name (map plainTV args) [] []+      normalizeDecFor reifiedDec dec+#endif+    ClassI{}                          -> bad "Class not supported"+    FamilyI DataFamilyD{} _           -> bad "Use a value constructor to reify a data family instance"+    FamilyI _ _                       -> bad "Type families not supported"+    TyConI dec                        -> normalizeDecFor reifiedDec dec+    DataConI name _ parent            -> reifyParent name parent+                                         -- NB: We do not pass the IsReifiedDec information here+                                         -- because there's no point. We have no choice but to+                                         -- call reify here, since we need to determine the+                                         -- parent data type/family.+    VarI recName recTy _              -> reifyRecordType recName recTy+                                         -- NB: Similarly, we do not pass the IsReifiedDec+                                         -- information here.+    _                                 -> bad "Expected a type constructor"+  where+    bad msg = fail (entry ++ ": " ++ msg)+++reifyParent :: Name -> Name -> Q DatatypeInfo+reifyParent con = reifyParentWith "reifyParent" p+  where+    p :: DatatypeInfo -> Bool+    p info = con `elem` map constructorName (datatypeCons info)++reifyRecordType :: Name -> Type -> Q DatatypeInfo+reifyRecordType recName recTy =+  let (_, _, argTys :|- _) = uncurryType recTy+  in case argTys of+       dataTy:_ -> decomposeDataType dataTy+       _        -> notRecSelFailure+  where+    decomposeDataType :: Type -> Q DatatypeInfo+    decomposeDataType ty =+      do case decomposeType ty of+           ConT parent :| _ -> reifyParentWith "reifyRecordType" p parent+           _                -> notRecSelFailure++    notRecSelFailure :: Q a+    notRecSelFailure = fail $+      "reifyRecordType: Not a record selector type: " +++      nameBase recName ++ " :: " ++ show recTy++    p :: DatatypeInfo -> Bool+    p info = any (conHasRecord recName) (datatypeCons info)++reifyParentWith ::+  String                 {- ^ prefix for error messages -} ->+  (DatatypeInfo -> Bool) {- ^ predicate for finding the right+                              data family instance -}      ->+  Name                   {- ^ parent data type name -}     ->+  Q DatatypeInfo+reifyParentWith prefix p n =+  do info <- reify n+     case info of+       TyConI dec -> normalizeDecFor isReified dec+       FamilyI dec instances ->+         do instances1 <- mapM (repairDataFam dec) instances+            instances2 <- mapM (normalizeDecFor isReified) instances1+            case find p instances2 of+              Just inst -> return inst+              Nothing   -> panic "lost the instance"+       _ -> panic "unexpected parent"+  where+    dataFamiliesOnOldGHCsError :: Q a+    dataFamiliesOnOldGHCsError = fail $+      prefix ++ ": Data family instances can only be reified with GHC 7.4 or later"++    panic :: String -> Q a+    panic message = fail $ "PANIC: " ++ prefix ++ " " ++ message++-- Sadly, Template Haskell's treatment of data family instances leaves much+-- to be desired. On all versions of GHC, TH leaves off the kind signatures on+-- the type patterns of data family instances where a kind signature isn't+-- specified explicitly. Here, we can use the parent data family's type variable+-- binders to reconstruct the kind signatures if they are missing.+repairDataFam ::+  Dec {- ^ family declaration   -} ->+  Dec {- ^ instance declaration -} ->+  Q Dec {- ^ instance declaration -}+repairDataFam famD instD+#if MIN_VERSION_template_haskell(2,15,0)+      | DataFamilyD _ dvars dk <- famD+      , NewtypeInstD cx mbInstVars nts k c deriv <- instD+      , con :| ts <- decomposeType nts+      = do ts' <- repairVarKindsWith dvars dk ts+           return $ NewtypeInstD cx mbInstVars (foldl' AppT con ts') k c deriv++      | DataFamilyD _ dvars dk <- famD+      , DataInstD cx mbInstVars nts k c deriv <- instD+      , con :| ts <- decomposeType nts+      = do ts' <- repairVarKindsWith dvars dk ts+           return $ DataInstD cx mbInstVars (foldl' AppT con ts') k c deriv+#else+      | DataFamilyD _ dvars dk <- famD+      , NewtypeInstD cx n ts k c deriv <- instD+      = do ts' <- repairVarKindsWith dvars dk ts+           return $ NewtypeInstD cx n ts' k c deriv++      | DataFamilyD _ dvars dk <- famD+      , DataInstD cx n ts k c deriv <- instD+      = do ts' <- repairVarKindsWith dvars dk ts+           return $ DataInstD cx n ts' k c deriv+#endif+repairDataFam _ instD = return instD++-- | @'repairVarKindsWith' tvbs mbKind ts@ returns @ts@, but where each element+-- has an explicit kind signature taken from a 'TyVarBndr' in the corresponding+-- position in @tvbs@, or from the corresponding kind argument in 'mbKind' if+-- there aren't enough 'TyVarBndr's available. An example where @tvbs@ can be+-- shorter than @ts@ can be found in this example from #95:+--+-- @+-- data family F :: Type -> Type+-- data instance F a = C+-- @+--+-- The @F@ has no type variable binders in its @data family@ declaration, and+-- it has a return kind of @Type -> Type@. As a result, we pair up @Type@ with+-- @VarT a@ to get @SigT a (ConT ''Type)@.+repairVarKindsWith :: [TyVarBndrVis] -> Maybe Kind -> [Type] -> Q [Type]+repairVarKindsWith tvbs mbKind ts = do+  extra_tvbs <- mkExtraKindBinders $ fromMaybe starK mbKind+  -- This list should be the same length as @ts@. If it isn't, something has+  -- gone terribly wrong.+  let tvbs' = changeTVFlags () tvbs ++ extra_tvbs+  return $ zipWith stealKindForType tvbs' ts++-- If a VarT is missing an explicit kind signature, steal it from a TyVarBndr.+stealKindForType :: TyVarBndr_ flag -> Type -> Type+stealKindForType tvb t@VarT{} = SigT t (tvKind tvb)+stealKindForType _   t        = t++-- | Normalize 'Dec' for a newtype or datatype into a 'DatatypeInfo'.+-- Fail in 'Q' otherwise.+--+-- Beware: 'normalizeDec' can have surprising behavior when it comes to fixity.+-- For instance, if you have this quasiquoted data declaration:+--+-- @+-- [d| infix 5 :^^:+--     data Foo where+--       (:^^:) :: Int -> Int -> Foo |]+-- @+--+-- Then if you pass the 'Dec' for @Foo@ to 'normalizeDec' without splicing it+-- in a previous Template Haskell splice, then @(:^^:)@ will be labeled a 'NormalConstructor'+-- instead of an 'InfixConstructor'. This is because Template Haskell has no way to+-- reify the fixity declaration for @(:^^:)@, so it must assume there isn't one. To+-- work around this behavior, use 'reifyDatatype' instead.+normalizeDec :: Dec -> Q DatatypeInfo+normalizeDec = normalizeDecFor isn'tReified++normalizeDecFor :: IsReifiedDec -> Dec -> Q DatatypeInfo+normalizeDecFor isReified dec =+  case dec of+#if MIN_VERSION_template_haskell(2,20,0)+    TypeDataD name tyvars mbKind cons ->+      normalizeDataD [] name tyvars mbKind cons TypeData+#endif+#if MIN_VERSION_template_haskell(2,12,0)+    NewtypeD context name tyvars mbKind con _derives ->+      normalizeDataD context name tyvars mbKind [con] Newtype+    DataD context name tyvars mbKind cons _derives ->+      normalizeDataD context name tyvars mbKind cons Datatype+# if MIN_VERSION_template_haskell(2,15,0)+    NewtypeInstD context mbTyvars nameInstTys mbKind con _derives ->+      normalizeDataInstDPostTH2'15 "newtype" context mbTyvars nameInstTys+                                   mbKind [con] NewtypeInstance+    DataInstD context mbTyvars nameInstTys mbKind cons _derives ->+      normalizeDataInstDPostTH2'15 "data" context mbTyvars nameInstTys+                                   mbKind cons DataInstance+# else+    NewtypeInstD context name instTys mbKind con _derives ->+      normalizeDataInstDPreTH2'15 context name instTys mbKind [con] NewtypeInstance+    DataInstD context name instTys mbKind cons _derives ->+      normalizeDataInstDPreTH2'15 context name instTys mbKind cons DataInstance+# endif+#else+    NewtypeD context name tyvars mbKind con _derives ->+      normalizeDataD context name tyvars mbKind [con] Newtype+    DataD context name tyvars mbKind cons _derives ->+      normalizeDataD context name tyvars mbKind cons Datatype+    NewtypeInstD context name instTys mbKind con _derives ->+      normalizeDataInstDPreTH2'15 context name instTys mbKind [con] NewtypeInstance+    DataInstD context name instTys mbKind cons _derives ->+      normalizeDataInstDPreTH2'15 context name instTys mbKind cons DataInstance+#endif+    _ -> fail "normalizeDecFor: DataD or NewtypeD required"+  where+    -- We only need to repair reified declarations for data family instances.+    repair13618' :: DatatypeInfo -> Q DatatypeInfo+    repair13618' di@DatatypeInfo{datatypeVariant = variant}+      | isReified && isFamInstVariant variant+      = repair13618 di+      | otherwise+      = return di++    -- If a data type lacks an explicit return kind, use `reifyType` to compute+    -- it, as described in step (1) of Note [Tricky result kinds].+    normalizeMbKind :: Name -> [Type] -> Maybe Kind -> Q (Maybe Kind)+    normalizeMbKind _name _instTys mbKind@(Just _) = return mbKind+    normalizeMbKind name instTys Nothing = do+#if MIN_VERSION_template_haskell(2,16,0)+      mbReifiedKind <- return Nothing `recover` fmap Just (reifyType name)+      T.mapM normalizeKind mbReifiedKind+      where+        normalizeKind :: Kind -> Q Kind+        normalizeKind k = do+          k' <- resolveKindSynonyms k+          -- Step (1) in Note [Tricky result kinds]+          -- (Wrinkle: normalizeMbKind argument unification).+          let (args, res) = unravelKindUpTo instTys k'+              -- Step (2) in Note [Tricky result kinds]+              -- (Wrinkle: normalizeMbKind argument unification).+              (instTys', args') =+                unzip $+                mapMaybe+                  (\(instTy, arg) ->+                    case arg of+                      VisFADep tvb -> Just (instTy, bndrParam tvb)+                      VisFAAnon k  -> (, k) <$> sigTMaybeKind instTy)+                  args+              (subst, _) = mergeArguments args' instTys'+          -- Step (3) in Note [Tricky result kinds]+          -- (Wrinkle: normalizeMbKind argument unification).+          pure $ applySubstitution (VarT <$> subst) res+#else+      return Nothing+#endif++    -- Given a data type declaration's binders, as well as the arguments and+    -- result of its explicit return kind, compute the free type variables.+    -- For example, this:+    --+    -- @+    -- data T (a :: j) :: forall k. Maybe k -> Type+    -- @+    --+    -- Would yield:+    --+    -- @+    -- [j, (a :: j), k, (b :: k)]+    -- @+    --+    -- Where @b@ is a fresh name that is generated in 'mkExtraFunArgForalls'.+    datatypeFreeVars :: [TyVarBndr_ flag] -> FunArgs -> Kind -> [TyVarBndrUnit]+    datatypeFreeVars declBndrs kindArgs kindRes =+      freeVariablesWellScoped $+      bndrParams declBndrs ++ funArgTys kindArgs ++ [kindRes]++    normalizeDataD :: Cxt -> Name -> [TyVarBndrVis] -> Maybe Kind+                   -> [Con] -> DatatypeVariant -> Q DatatypeInfo+    normalizeDataD context name tyvars mbKind cons variant = do+      -- NB: use `filter isRequiredTvb tyvars` here. It is possible for some of+      -- the `tyvars` to be `BndrInvis` if the data type is quoted, e.g.,+      --+      --   data D @k (a :: k)+      --+      -- th-abstraction adopts the convention that all binders in the+      -- 'datatypeInstTypes' are required, so we want to filter out the `@k`.+      let tys = bndrParams $ filter isRequiredTvb tyvars+      mbKind' <- normalizeMbKind name tys mbKind+      normalize' context name tyvars tys mbKind' cons variant++    normalizeDataInstDPostTH2'15+      :: String -> Cxt -> Maybe [TyVarBndrUnit] -> Type -> Maybe Kind+      -> [Con] -> DatatypeVariant -> Q DatatypeInfo+    normalizeDataInstDPostTH2'15 what context mbTyvars nameInstTys+                                 mbKind cons variant =+      case decomposeType nameInstTys of+        ConT name :| instTys -> do+          mbKind' <- normalizeMbKind name instTys mbKind+          normalize' context name+                     (fromMaybe (freeVariablesWellScoped instTys) mbTyvars)+                     instTys mbKind' cons variant+        _ -> fail $ "Unexpected " ++ what ++ " instance head: " ++ pprint nameInstTys++    normalizeDataInstDPreTH2'15+      :: Cxt -> Name -> [Type] -> Maybe Kind+      -> [Con] -> DatatypeVariant -> Q DatatypeInfo+    normalizeDataInstDPreTH2'15 context name instTys mbKind cons variant = do+      mbKind' <- normalizeMbKind name instTys mbKind+      normalize' context name (freeVariablesWellScoped instTys)+                 instTys mbKind' cons variant++    -- The main worker of this function.+    normalize' :: Cxt -> Name -> [TyVarBndr_ flag] -> [Type] -> Maybe Kind+               -> [Con] -> DatatypeVariant -> Q DatatypeInfo+    normalize' context name tvbs instTys mbKind cons variant = do+      -- If `mbKind` is *still* Nothing after all of the work done in+      -- normalizeMbKind, then conservatively assume that the return kind is+      -- `Type`. See step (1) of Note [Tricky result kinds].+      let kind = fromMaybe starK mbKind+      kind' <- resolveKindSynonyms kind+      let (kindArgs, kindRes) = unravelType kind'+      (extra_vis_tvbs, kindArgs') <- mkExtraFunArgForalls kindArgs+      let tvbs'    = datatypeFreeVars tvbs kindArgs' kindRes+          instTys' = instTys ++ bndrParams extra_vis_tvbs+      dec <- normalizeDec' isReified context name tvbs' instTys' kindRes cons variant+      repair13618' $ giveDIVarsStarKinds isReified dec++{-+Note [Tricky result kinds]+~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this example, which uses UnliftedNewtypes:++  type T :: TYPE r+  newtype T where+    MkT :: forall r. Any @(TYPE r) -> T @r++This has one universally quantified type variable `r`, but making+`reifyDatatype ''T` realize this is surprisingly tricky. There root of the+trickiness is the fact that `Language.Haskell.TH.reify ''T` will yield this:++  newtype T where+    MkT :: forall r. (Any :: TYPE r) -> (T :: TYPE r)++In particular, note that:++1. `reify` does not give `T` an explicit return kind of `TYPE r`. This is bad,+   because without this, we cannot conclude that `r` is universally quantified.+2. The reified type of the `MkT` constructor uses explicit kind annotations+   instead of visible kind applications. That is, the return type is+   `T :: TYPE r` instead of `T @r`. This makes it even trickier to figure out+   that `r` is universally quantified, as `r` does not appear directly+   underneath an application of `T`.++We resolve each of these issues as follows:++1. In `normalizeDecFor.normalizeMbKind`, we attempt to use `reifyType` to look+   up the return kind of the data type. In the `T` example above, this suffices+   to conclude that `T :: TYPE r`. `reifyType` won't always work (e.g., when+   using `normalizeDec` on a data type without an explicit return kind), so for+   those situations, we conservatively assume that the data type has return kind+   `Type`.++   The implementation of `normalizeMbKind` is somewhat involved. See+   "Wrinkle: normalizeMbKind argument unification" below for more details.+2. After determining the result kind `K1`, we pass `K1` through to+   `normalizeGadtC`. In that function, we check if the return type of the data+   constructor is of the form `Ty :: K2`, and if so, we attempt to unify `K1`+   and `K2` by passing through to `mergeArguments`. In the example above, this+   lets us conclude that the `r` in the data type return kind is the same `r`+   as in the data constructor.++===================================================+== Wrinkle: normalizeMbKind argument unification ==+===================================================++Here is a slightly more involved example:++  type T2 :: TYPE r1 -> TYPE r1+  newtype T2 (a :: TYPE r2) = MkT2 a++Here, we must use `reifyType` in `normalizeMbKind` to determine that the return+kind is `TYPE r1`. But we must be careful here: `r1` is actually the same type+variable as `r2`! We don't want to accidentally end up quantifying over the two+variables separately in `datatypeInstVars`, since they're really one and the+same.++We accomplish this by doing the following:++1. After calling `reifyKind` in `normalizeMbKind`, split the result kind into+   as many arguments as there are visible binders in the data type declaration.+   In the `T2` example above, there is exactly one visible binder in+   `newtype T2 a`, so we split the kind `TYPE r1 -> TYPE r1` by one argument to+   get ([TYPE r1], TYPE r1). See `unravelKindUpTo` for how this splitting logic+   is implemented.+2. We then unify the argument kinds resuling from the splitting in the previous+   step with the corresponding kinds from the data type declaration. In the+   example above, the split argument kind is `TYPE r1`, and the binder in the+   declaration has kind `TYPE r2`, so we unify `TYPE r1` with `TYPE r2` using+   `mergeArguments` to get a substitution [r1 :-> r2].+3. We then apply the substitution from the previous step to the rest of the+   kind. In the example above, that means we apply the [r1 :-> r2] substitution+   to `TYPE r1` to obtain `TYPE r2`.++The payoff is that everything consistently refers to `r2`, rather than the mix+of `r1` and `r2` as before.+-}++-- | 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@.+-- 'mkExtraKindBinders' 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.+mkExtraKindBinders :: Kind -> Q [TyVarBndrUnit]+mkExtraKindBinders kind = do+  kind' <- resolveKindSynonyms kind+  let (args, _) = unravelType kind'+  (extra_kvbs, _) <- mkExtraFunArgForalls args+  return extra_kvbs++-- | Take the supplied function kind arguments ('FunArgs') and do two things:+--+-- 1. For each 'FAAnon' with kind @k@, generate a fresh name @a@ and return+--    the 'TyVarBndr' @a :: k@. Also return each visible @forall@ in an+--    'FAForalls' as a 'TyVarBndr'. (This is what the list of 'TyVarBndrUnit's+--    in the return type consists of.)+--+-- 2. Return a new 'FunArgs' value where each 'FAAnon' has been replaced with+--    @'FAForalls' ('ForallVis' [a :: k])@, where @a :: k@ the corresponding+--    'TyVarBndr' computed in step (1).+--+-- As an example, consider this function kind:+--+-- @+-- forall k. k -> Type -> Type+-- @+--+-- After splitting this kind into its 'FunArgs':+--+-- @+-- ['FAForalls' ('ForallInvis' [k]), 'FAAnon' k, 'FAAnon' Type]+-- @+--+-- Calling 'mkExtraFunArgForalls' on this 'FunArgs' value would return:+--+-- @+-- ( [a :: k, b :: Type]+-- , [ 'FAForalls' ('ForallInvis' [k])+--   , 'FAForalls' ('ForallVis' [a :: k])+--   , 'FAForalls' ('ForallVis' [b :: Type])+--   ]+-- )+-- @+--+-- Where @a@ and @b@ are fresh.+--+-- This function is used in two places:+--+-- 1. As the workhorse for 'mkExtraKindBinders'.+--+-- 2. In 'normalizeDecFor', as part of computing the 'datatypeInstVars' and as+--    part of eta expanding the explicit return kind.+mkExtraFunArgForalls :: FunArgs -> Q ([TyVarBndrUnit], FunArgs)+mkExtraFunArgForalls FANil =+  return ([], FANil)+mkExtraFunArgForalls (FAForalls tele args) = do+  (extra_vis_tvbs', args') <- mkExtraFunArgForalls args+  case tele of+    ForallVis tvbs ->+      return ( tvbs ++ extra_vis_tvbs'+             , FAForalls (ForallVis tvbs) args'+             )+    ForallInvis tvbs ->+      return ( extra_vis_tvbs'+             , FAForalls (ForallInvis tvbs) args'+             )+mkExtraFunArgForalls (FACxt ctxt args) = do+  (extra_vis_tvbs', args') <- mkExtraFunArgForalls args+  return (extra_vis_tvbs', FACxt ctxt args')+mkExtraFunArgForalls (FAAnon anon args) = do+  name <- newName "x"+  let tvb = kindedTV name anon+  (extra_vis_tvbs', args') <- mkExtraFunArgForalls args+  return ( tvb : extra_vis_tvbs'+         , FAForalls (ForallVis [tvb]) args'+         )++-- | Is a declaration for a @data instance@ or @newtype instance@?+isFamInstVariant :: DatatypeVariant -> Bool+isFamInstVariant dv =+  case dv of+    Datatype        -> False+    Newtype         -> False+    DataInstance    -> True+    NewtypeInstance -> True+    TypeData        -> False++bndrParams :: [TyVarBndr_ flag] -> [Type]+bndrParams = map bndrParam++bndrParam :: TyVarBndr_ flag -> Type+bndrParam = elimTV VarT (\n k -> SigT (VarT n) k)++-- | Returns 'True' if the flag of the supplied 'TyVarBndrVis' is 'BndrReq'.+isRequiredTvb :: TyVarBndrVis -> Bool+isRequiredTvb tvb = tvFlag tvb == BndrReq++-- | Remove the outermost 'SigT'.+stripSigT :: Type -> Type+stripSigT (SigT t _) = t+stripSigT t          = t++-- | If the supplied 'Type' is a @'SigT' _ k@, return @'Just' k@. Otherwise,+-- return 'Nothing'.+sigTMaybeKind :: Type -> Maybe Kind+sigTMaybeKind (SigT _ k) = Just k+sigTMaybeKind _          = Nothing++normalizeDec' ::+  IsReifiedDec    {- ^ Is this a reified 'Dec'? -} ->+  Cxt             {- ^ Datatype context         -} ->+  Name            {- ^ Type constructor         -} ->+  [TyVarBndrUnit] {- ^ Type parameters          -} ->+  [Type]          {- ^ Argument types           -} ->+  Kind            {- ^ Result kind              -} ->+  [Con]           {- ^ Constructors             -} ->+  DatatypeVariant {- ^ Extra information        -} ->+  Q DatatypeInfo+normalizeDec' reifiedDec context name params instTys resKind cons variant =+  do cons' <- concat <$> mapM (normalizeConFor reifiedDec name params instTys resKind variant) cons+     return DatatypeInfo+       { datatypeContext   = context+       , datatypeName      = name+       , datatypeVars      = params+       , datatypeInstTypes = instTys+       , datatypeCons      = cons'+       , datatypeReturnKind = resKind+       , datatypeVariant   = variant+       }++-- | Normalize a 'Con' into a 'ConstructorInfo'. This requires knowledge of+-- the type and parameters of the constructor, as well as whether the constructor+-- is for a data family instance, as extracted from the outer+-- 'Dec'.+normalizeCon ::+  Name            {- ^ Type constructor  -} ->+  [TyVarBndrUnit] {- ^ Type parameters   -} ->+  [Type]          {- ^ Argument types    -} ->+  Kind            {- ^ Result kind       -} ->+  DatatypeVariant {- ^ Extra information -} ->+  Con             {- ^ Constructor       -} ->+  Q [ConstructorInfo]+normalizeCon = normalizeConFor isn'tReified++normalizeConFor ::+  IsReifiedDec    {- ^ Is this a reified 'Dec'? -} ->+  Name            {- ^ Type constructor         -} ->+  [TyVarBndrUnit] {- ^ Type parameters          -} ->+  [Type]          {- ^ Argument types           -} ->+  Kind            {- ^ Result kind              -} ->+  DatatypeVariant {- ^ Extra information        -} ->+  Con             {- ^ Constructor              -} ->+  Q [ConstructorInfo]+normalizeConFor reifiedDec typename params instTys resKind variant =+  fmap (map (giveCIVarsStarKinds reifiedDec)) . dispatch+  where+    -- A GADT constructor is declared infix when:+    --+    -- 1. Its name uses operator syntax (e.g., (:*:))+    -- 2. It has exactly two fields+    -- 3. It has a programmer-supplied fixity declaration+    checkGadtFixity :: [Type] -> Name -> Q ConstructorVariant+    checkGadtFixity ts n = do+      -- Don't call reifyFixityCompat here! We need to be able to distinguish+      -- between a default fixity and an explicit @infixl 9@.+      mbFi <- return Nothing `recover` reifyFixity n+      let userSuppliedFixity = isJust mbFi+      return $ if isInfixDataCon (nameBase n)+                  && length ts == 2+                  && userSuppliedFixity+               then InfixConstructor+               else NormalConstructor++    -- Checks if a String names a valid Haskell infix data+    -- constructor (i.e., does it begin with a colon?).+    isInfixDataCon :: String -> Bool+    isInfixDataCon (':':_) = True+    isInfixDataCon _       = False++    dispatch :: Con -> Q [ConstructorInfo]+    dispatch =+      let defaultCase :: Con -> Q [ConstructorInfo]+          defaultCase = go [] [] False+            where+              go :: [TyVarBndrUnit]+                 -> Cxt+                 -> Bool -- Is this a GADT? (see the documentation for+                         -- for checkGadtFixity)+                 -> Con+                 -> Q [ConstructorInfo]+              go tyvars context gadt c =+                case c of+                  NormalC n xs -> do+                    let (bangs, ts) = unzip xs+                        stricts     = map normalizeStrictness bangs+                    fi <- if gadt+                             then checkGadtFixity ts n+                             else return NormalConstructor+                    return [ConstructorInfo n tyvars context ts stricts fi]+                  InfixC l n r ->+                    let (bangs, ts) = unzip [l,r]+                        stricts     = map normalizeStrictness bangs in+                    return [ConstructorInfo n tyvars context ts stricts+                                            InfixConstructor]+                  RecC n xs ->+                    let fns     = takeFieldNames xs+                        stricts = takeFieldStrictness xs in+                    return [ConstructorInfo n tyvars context+                              (takeFieldTypes xs) stricts (RecordConstructor fns)]+                  ForallC tyvars' context' c' ->+                    go (changeTVFlags () tyvars'++tyvars) (context'++context) True c'+                  GadtC ns xs innerType ->+                    let (bangs, ts) = unzip xs+                        stricts     = map normalizeStrictness bangs in+                    gadtCase ns innerType ts stricts (checkGadtFixity ts)+                  RecGadtC ns xs innerType ->+                    let fns     = takeFieldNames xs+                        stricts = takeFieldStrictness xs in+                    gadtCase ns innerType (takeFieldTypes xs) stricts+                             (const $ return $ RecordConstructor fns)+                where+                  gadtCase = normalizeGadtC typename params instTys resKind tyvars context+      in defaultCase++normalizeStrictness :: Bang -> FieldStrictness+normalizeStrictness (Bang upk str) =+  FieldStrictness (normalizeSourceUnpackedness upk)+                  (normalizeSourceStrictness str)+  where+    normalizeSourceUnpackedness :: SourceUnpackedness -> Unpackedness+    normalizeSourceUnpackedness NoSourceUnpackedness = UnspecifiedUnpackedness+    normalizeSourceUnpackedness SourceNoUnpack       = NoUnpack+    normalizeSourceUnpackedness SourceUnpack         = Unpack++    normalizeSourceStrictness :: SourceStrictness -> Strictness+    normalizeSourceStrictness NoSourceStrictness = UnspecifiedStrictness+    normalizeSourceStrictness SourceLazy         = Lazy+    normalizeSourceStrictness SourceStrict       = Strict++normalizeGadtC ::+  Name              {- ^ Type constructor             -} ->+  [TyVarBndrUnit]   {- ^ Type parameters              -} ->+  [Type]            {- ^ Argument types               -} ->+  Kind              {- ^ Result kind                  -} ->+  [TyVarBndrUnit]   {- ^ Constructor parameters       -} ->+  Cxt               {- ^ Constructor context          -} ->+  [Name]            {- ^ Constructor names            -} ->+  Type              {- ^ Declared type of constructor -} ->+  [Type]            {- ^ Constructor field types      -} ->+  [FieldStrictness] {- ^ Constructor field strictness -} ->+  (Name -> Q ConstructorVariant)+                    {- ^ Determine a constructor variant+                         from its 'Name' -}              ->+  Q [ConstructorInfo]+normalizeGadtC typename params instTys resKind tyvars context names innerType+               fields stricts getVariant =+  do -- It's possible that the constructor has implicitly quantified type+     -- variables, such as in the following example (from #58):+     --+     --   [d| data Foo where+     --         MkFoo :: a -> Foo |]+     --+     -- normalizeGadtC assumes that all type variables have binders, however,+     -- so we use freeVariablesWellScoped to obtain the implicit type+     -- variables' binders before proceeding.+     let implicitTyvars = freeVariablesWellScoped+                          [curryType (changeTVFlags SpecifiedSpec tyvars)+                                     context fields innerType]+         allTyvars = implicitTyvars ++ tyvars++     -- Due to GHC Trac #13885, it's possible that the type variables bound by+     -- a GADT constructor will shadow those that are bound by the data type.+     -- This function assumes this isn't the case in certain parts (e.g., when+     -- mergeArguments is invoked), so we do an alpha-renaming of the+     -- constructor-bound variables before proceeding. See #36 for an example+     -- of what can go wrong if this isn't done.+     let conBoundNames =+           concatMap (\tvb -> tvName tvb:freeVariables (tvKind tvb)) allTyvars+     conSubst <- T.sequence $ Map.fromList [ (n, newName (nameBase n))+                                           | n <- conBoundNames ]+     let conSubst'     = fmap VarT conSubst+         renamedTyvars =+           map (elimTV (\n   -> plainTV  (conSubst Map.! n))+                       (\n k -> kindedTV (conSubst Map.! n)+                                         (applySubstitution conSubst' k))) allTyvars+         renamedContext   = applySubstitution conSubst' context+         renamedInnerType = applySubstitution conSubst' innerType+         renamedFields    = applySubstitution conSubst' fields++     innerType' <- resolveTypeSynonyms renamedInnerType++     -- If the return type in the data constructor is of the form `T :: K`, then+     -- return (T, Just K, Just resKind), where `resKind` is the result kind of+     -- the parent data type. Otherwise, return (T :: K, Nothing, Nothing). The+     -- two `Maybe` values are passed below to `mergeArguments` such that if+     -- they are both `Just`, then we will attempt to unify `K` and `resKind`.+     -- See step (2) of Note [Tricky result kinds].+     let (innerType'', mbInnerResKind, mbResKind) =+           case innerType' of+             SigT t innerResKind -> (t, Just innerResKind, Just resKind)+             _                   -> (innerType', Nothing, Nothing)++     case decomposeType innerType'' of+       ConT innerTyCon :| ts | typename == innerTyCon ->++         let -- See step (2) of Note [Tricky result kinds].+             instTys' = maybeToList mbResKind ++ instTys+             ts' = maybeToList mbInnerResKind ++ ts++             (substName, context1) =+               closeOverKinds (kindsOfFVsOfTvbs renamedTyvars)+                              (kindsOfFVsOfTvbs params)+                              (mergeArguments instTys' ts')+             subst    = VarT <$> substName+             exTyvars = [ tv | tv <- renamedTyvars, Map.notMember (tvName tv) subst ]++             -- The use of substTyVarBndrKinds below will never capture, as the+             -- range of the substitution will always use distinct names from+             -- exTyvars due to the alpha-renaming pass above.+             exTyvars' = substTyVarBndrKinds subst exTyvars+             context2  = applySubstitution   subst (context1 ++ renamedContext)+             fields'   = applySubstitution   subst renamedFields+         in sequence [ ConstructorInfo name exTyvars' context2+                                       fields' stricts <$> variantQ+                     | name <- names+                     , let variantQ = getVariant name+                     ]++       _ -> fail "normalizeGadtC: Expected type constructor application"++{-+Extend a type variable renaming subtitution and a list of equality+predicates by looking into kind information as much as possible.++Why is this necessary? Consider the following example:++  data (a1 :: k1) :~: (b1 :: k1) where+    Refl :: forall k2 (a2 :: k2). a2 :~: a2++After an initial call to mergeArguments, we will have the following+substitution and context:++* Substitution: [a2 :-> a1]+* Context: (a2 ~ b1)++We shouldn't stop there, however! We determine the existentially quantified+type variables of a constructor by filtering out those constructor-bound+variables which do not appear in the substitution that mergeArguments+returns. In this example, Refl's bound variables are k2 and a2. a2 appears+in the returned substitution, but k2 does not, which means that we would+mistakenly conclude that k2 is existential!++Although we don't have the full power of kind inference to guide us here, we+can at least do the next best thing. Generally, the datatype-bound type+variables and the constructor type variable binders contain all of the kind+information we need, so we proceed as follows:++1. Construct a map from each constructor-bound variable to its kind. (Do the+   same for each datatype-bound variable). These maps are the first and second+   arguments to closeOverKinds, respectively.+2. Call mergeArguments once on the GADT return type and datatype-bound types,+   and pass that in as the third argument to closeOverKinds.+3. For each name-name pair in the supplied substitution, check if the first and+   second names map to kinds in the first and second kind maps in+   closeOverKinds, respectively. If so, associate the first kind with the+   second kind.+4. For each kind association discovered in part (3), call mergeArguments+   on the lists of kinds. This will yield a kind substitution and kind+   equality context.+5. If the kind substitution is non-empty, then go back to step (3) and repeat+   the process on the new kind substitution and context.++   Otherwise, if the kind substitution is empty, then we have reached a fixed-+   point (i.e., we have closed over the kinds), so proceed.+6. Union up all of the substitutions and contexts, and return those.++This algorithm is not perfect, as it will only catch everything if all of+the kinds are explicitly mentioned somewhere (and not left quantified+implicitly). Thankfully, reifying data types via Template Haskell tends to+yield a healthy amount of kind signatures, so this works quite well in+practice.+-}+closeOverKinds :: Map Name Kind+               -> Map Name Kind+               -> (Map Name Name, Cxt)+               -> (Map Name Name, Cxt)+closeOverKinds domainFVKinds rangeFVKinds = go+  where+    go :: (Map Name Name, Cxt) -> (Map Name Name, Cxt)+    go (subst, context) =+      let substList = Map.toList subst+          (kindsInner, kindsOuter) =+            unzip $+            mapMaybe (\(d, r) -> do d' <- Map.lookup d domainFVKinds+                                    r' <- Map.lookup r rangeFVKinds+                                    return (d', r'))+                     substList+          (kindSubst, kindContext) = mergeArguments kindsOuter kindsInner+          (restSubst, restContext)+            = if Map.null kindSubst -- Fixed-point calculation+                 then (Map.empty, [])+                 else go (kindSubst, kindContext)+          finalSubst   = Map.unions [subst, kindSubst, restSubst]+          finalContext = nub $ concat [context, kindContext, restContext]+            -- Use `nub` here in an effort to minimize the number of+            -- redundant equality constraints in the returned context.+      in (finalSubst, finalContext)++-- Look into a list of types and map each free variable name to its kind.+kindsOfFVsOfTypes :: [Type] -> Map Name Kind+kindsOfFVsOfTypes = foldMap go+  where+    go :: Type -> Map Name Kind+    go (AppT t1 t2) = go t1 `Map.union` go t2+    go (SigT t k) =+      let kSigs = go k+      in case t of+           VarT n -> Map.insert n k kSigs+           _      -> go t `Map.union` kSigs++    go (ForallT {})    = forallError+#if MIN_VERSION_template_haskell(2,16,0)+    go (ForallVisT {}) = forallError+#endif++    go _ = Map.empty++    forallError :: a+    forallError = error "`forall` type used in data family pattern"++-- Look into a list of type variable binder and map each free variable name+-- to its kind (also map the names that KindedTVs bind to their respective+-- kinds). This function considers the kind of a PlainTV to be *.+kindsOfFVsOfTvbs :: [TyVarBndr_ flag] -> Map Name Kind+kindsOfFVsOfTvbs = foldMap go+  where+    go :: TyVarBndr_ flag -> Map Name Kind+    go = elimTV (\n -> Map.singleton n starK)+                (\n k -> let kSigs = kindsOfFVsOfTypes [k]+                         in Map.insert n k kSigs)++mergeArguments ::+  [Type] {- ^ outer parameters                    -} ->+  [Type] {- ^ inner parameters (specializations ) -} ->+  (Map Name Name, Cxt)+mergeArguments ns ts = foldr aux (Map.empty, []) (zip ns ts)+  where++    aux (f `AppT` x, g `AppT` y) sc =+      aux (x,y) (aux (f,g) sc)++    aux (VarT n,p) (subst, context) =+      case p of+        VarT m | m == n  -> (subst, context)+                   -- If the two variables are the same, don't bother extending+                   -- the substitution. (This is purely an optimization.)+               | Just n' <- Map.lookup m subst+               , n == n' -> (subst, context)+                   -- If a variable is already in a substitution and it maps+                   -- to the variable that we are trying to unify with, then+                   -- leave the context alone. (Not doing so caused #46.)+               | Map.notMember m subst -> (Map.insert m n subst, context)+        _ -> (subst, equalPred (VarT n) p : context)++    aux (SigT x _, y) sc = aux (x,y) sc -- learn about kinds??+    -- This matches *after* VarT so that we can compute a substitution+    -- that includes the kind signature.+    aux (x, SigT y _) sc = aux (x,y) sc++    aux _ sc = sc++-- | Expand all of the type synonyms in a type.+--+-- Note that this function will drop parentheses as a side effect.+resolveTypeSynonyms :: Type -> Q Type+resolveTypeSynonyms t =+  let (f, xs) = decomposeTypeArgs t+      normal_xs = filterTANormals xs++      -- Either the type is not headed by a type synonym, or it is headed by a+      -- type synonym that is not applied to enough arguments. Leave the type+      -- alone and only expand its arguments.+      defaultCase :: Type -> Q Type+      defaultCase ty = foldl appTypeArg ty <$> mapM resolveTypeArgSynonyms xs++      expandCon :: Name -- The Name to check whether it is a type synonym or not+                -> Type -- The argument type to fall back on if the supplied+                        -- Name isn't a type synonym+                -> Q Type+      expandCon n ty = do+        mbInfo <- reifyMaybe n+        case mbInfo of+          Just (TyConI (TySynD _ synvars def))+            |  length normal_xs >= length synvars -- Don't expand undersaturated type synonyms (#88)+            -> resolveTypeSynonyms $ expandSynonymRHS synvars normal_xs def+          _ -> defaultCase ty++  in case f of+       ForallT tvbs ctxt body ->+         ForallT `fmap` mapM resolve_tvb_syns tvbs+                   `ap` mapM resolvePredSynonyms ctxt+                   `ap` resolveTypeSynonyms body+       SigT ty ki -> do+         ty' <- resolveTypeSynonyms ty+         ki' <- resolveKindSynonyms ki+         defaultCase $ SigT ty' ki'+       ConT n -> expandCon n f+       InfixT t1 n t2 -> do+         t1' <- resolveTypeSynonyms t1+         t2' <- resolveTypeSynonyms t2+         expandCon n (InfixT t1' n t2')+       UInfixT t1 n t2 -> do+         t1' <- resolveTypeSynonyms t1+         t2' <- resolveTypeSynonyms t2+         expandCon n (UInfixT t1' n t2')+#if MIN_VERSION_template_haskell(2,15,0)+       ImplicitParamT n t -> do+         ImplicitParamT n <$> resolveTypeSynonyms t+#endif+#if MIN_VERSION_template_haskell(2,16,0)+       ForallVisT tvbs body ->+         ForallVisT `fmap` mapM resolve_tvb_syns tvbs+                      `ap` resolveTypeSynonyms body+#endif+#if MIN_VERSION_template_haskell(2,19,0)+       PromotedInfixT t1 n t2 -> do+         t1' <- resolveTypeSynonyms t1+         t2' <- resolveTypeSynonyms t2+         return $ PromotedInfixT t1' n t2'+       PromotedUInfixT t1 n t2 -> do+         t1' <- resolveTypeSynonyms t1+         t2' <- resolveTypeSynonyms t2+         return $ PromotedUInfixT t1' n t2'+#endif+       _ -> defaultCase f++-- | Expand all of the type synonyms in a 'TypeArg'.+resolveTypeArgSynonyms :: TypeArg -> Q TypeArg+resolveTypeArgSynonyms (TANormal t) = TANormal <$> resolveTypeSynonyms t+resolveTypeArgSynonyms (TyArg k)    = TyArg    <$> resolveKindSynonyms k++-- | Expand all of the type synonyms in a 'Kind'.+resolveKindSynonyms :: Kind -> Q Kind+resolveKindSynonyms = resolveTypeSynonyms++-- | Expand all of the type synonyms in a the kind of a 'TyVarBndr'.+resolve_tvb_syns :: TyVarBndr_ flag -> Q (TyVarBndr_ flag)+resolve_tvb_syns = mapMTVKind resolveKindSynonyms++expandSynonymRHS ::+  [TyVarBndr_ flag] {- ^ Substitute these variables... -} ->+  [Type]            {- ^ ...with these types... -} ->+  Type              {- ^ ...inside of this type. -} ->+  Type+expandSynonymRHS synvars ts def =+  let argNames    = map tvName synvars+      (args,rest) = splitAt (length argNames) ts+      subst       = Map.fromList (zip argNames args)+  in foldl AppT (applySubstitution subst def) rest++-- | Expand all of the type synonyms in a 'Pred'.+resolvePredSynonyms :: Pred -> Q Pred+resolvePredSynonyms = resolveTypeSynonyms++-- | Decompose a type into a list of it's outermost applications. This process+-- forgets about infix application, explicit parentheses, and visible kind+-- applications.+--+-- This operation should be used after all 'UInfixT' cases have been resolved+-- by 'resolveFixities' if the argument is being user generated.+--+-- > t ~= foldl1 AppT (decomposeType t)+decomposeType :: Type -> NonEmpty Type+decomposeType t =+  case decomposeTypeArgs t of+    (f, x) -> f :| filterTANormals x++-- | A variant of 'decomposeType' that preserves information about visible kind+-- applications by returning a 'NonEmpty' list of 'TypeArg's.+decomposeTypeArgs :: Type -> (Type, [TypeArg])+decomposeTypeArgs = go []+  where+    go :: [TypeArg] -> Type -> (Type, [TypeArg])+    go args (AppT f x)     = go (TANormal x:args) f+    go args (ParensT t)    = go args t+#if MIN_VERSION_template_haskell(2,15,0)+    go args (AppKindT f x) = go (TyArg x:args) f+#endif+    go args t              = (t, args)++-- | An argument to a type, either a normal type ('TANormal') or a visible+-- kind application ('TyArg').+data TypeArg+  = TANormal Type+  | TyArg Kind++-- | Apply a 'Type' to a 'TypeArg'.+appTypeArg :: Type -> TypeArg -> Type+appTypeArg f (TANormal x) = f `AppT` x+appTypeArg f (TyArg _k) =+#if MIN_VERSION_template_haskell(2,15,0)+  f `AppKindT` _k+#else+  f -- VKA isn't supported, so conservatively drop the argument+#endif++-- | Filter out all of the normal type arguments from a list of 'TypeArg's.+filterTANormals :: [TypeArg] -> [Type]+filterTANormals = mapMaybe f+  where+    f :: TypeArg -> Maybe Type+    f (TANormal t) = Just t+    f (TyArg {})   = Nothing++-- 'NonEmpty' didn't move into base until recently. Reimplementing it locally+-- saves dependencies for supporting older GHCs+data NonEmpty a = a :| [a]++data NonEmptySnoc a = [a] :|- a++-- Decompose a function type into its context, argument types,+-- and return type. For instance, this+--+--   forall a b. (Show a, b ~ Int) => (a -> b) -> Char -> Int+--+-- becomes+--+--   ([a, b], [Show a, b ~ Int], [a -> b, Char] :|- Int)+uncurryType :: Type -> ([TyVarBndrSpec], Cxt, NonEmptySnoc Type)+uncurryType = go [] [] []+  where+    go tvbs ctxt args (AppT (AppT ArrowT t1) t2) = go tvbs ctxt (t1:args) t2+    go tvbs ctxt args (ForallT tvbs' ctxt' t)    = go (tvbs++tvbs') (ctxt++ctxt') args t+    go tvbs ctxt args t                          = (tvbs, ctxt, reverse args :|- t)++-- Reconstruct a function type from its type variable binders, context,+-- argument types and return type.+curryType :: [TyVarBndrSpec] -> Cxt -> [Type] -> Type -> Type+curryType tvbs ctxt args res =+  ForallT tvbs ctxt $ foldr (\arg t -> ArrowT `AppT` arg `AppT` t) res args++-- All of the code from @ForallTelescope@ through @unravelType@ is taken from+-- the @th-desugar@ library, which is licensed under a 3-Clause BSD license.++-- | 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+  = ForallVis [TyVarBndrUnit]+    -- ^ A visible @forall@ (e.g., @forall a -> {...}@).+    --   These do not have any notion of specificity, so we use+    --   '()' as a placeholder value in the 'TyVarBndr's.+  | ForallInvis [TyVarBndrSpec]+    -- ^ An invisible @forall@ (e.g., @forall a {b} c -> {...}@),+    --   where each binder has a 'Specificity'.++-- | The list of arguments in a function 'Type'.+data FunArgs+  = FANil+    -- ^ No more arguments.+  | FAForalls ForallTelescope FunArgs+    -- ^ A series of @forall@ed 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@.+  | FACxt Cxt FunArgs+    -- ^ A series of constraint arguments followed by @=>@. For example,+    --   the @(c1, ..., cn)@ in @(c1, ..., cn) => r@.+  | FAAnon Kind FunArgs+    -- ^ An anonymous argument followed by an arrow. For example, the @a@+    --   in @a -> r@.++-- | 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+  = VisFADep TyVarBndrUnit+    -- ^ A visible @forall@ (e.g., @forall a -> a@).+  | VisFAAnon Kind+    -- ^ An anonymous argument followed by an arrow (e.g., @a -> r@).++-- | Decompose a function 'Type' into its arguments (the 'FunArgs') and its+-- result type (the 'Type).+unravelType :: Type -> (FunArgs, Type)+unravelType (ForallT tvbs cxt ty) =+  let (args, res) = unravelType ty in+  (FAForalls (ForallInvis tvbs) (FACxt cxt args), res)+unravelType (AppT (AppT ArrowT t1) t2) =+  let (args, res) = unravelType t2 in+  (FAAnon t1 args, res)+#if __GLASGOW_HASKELL__ >= 809+unravelType (ForallVisT tvbs ty) =+  let (args, res) = unravelType ty in+  (FAForalls (ForallVis tvbs) args, res)+#endif+unravelType t = (FANil, t)++-- | Reconstruct an arrow 'Type' from its argument and result types.+ravelType :: FunArgs -> Type -> Type+ravelType FANil res = res+-- We need a special case for FAForalls ForallInvis followed by FACxt so that we may+-- collapse them into a single ForallT when raveling.+ravelType (FAForalls (ForallInvis tvbs) (FACxt p args)) res =+  ForallT tvbs p (ravelType args res)+ravelType (FAForalls (ForallInvis  tvbs)  args)  res = ForallT tvbs [] (ravelType args res)+ravelType (FAForalls (ForallVis   _tvbs) _args) _res =+#if __GLASGOW_HASKELL__ >= 809+      ForallVisT _tvbs (ravelType _args _res)+#else+      error "Visible dependent quantification supported only on GHC 8.10+"+#endif+ravelType (FACxt cxt args) res = ForallT [] cxt (ravelType args res)+ravelType (FAAnon t args)  res = AppT (AppT ArrowT t) (ravelType args res)++-- | Convert a 'FunArg's value into the list of 'Type's that it contains.+-- For example, given this function type:+--+-- @+-- forall k (a :: k). Proxy a -> forall b. Maybe b+-- @+--+-- Then calling @funArgTys@ on the arguments would yield:+--+-- @+-- [k, (a :: k), Proxy a, b, Maybe b]+-- @+--+-- This is primarily used for the purposes of computing all of the type+-- variables that appear in a 'FunArgs' value.+funArgTys :: FunArgs -> [Type]+funArgTys FANil = []+funArgTys (FAForalls tele args) =+  forallTelescopeTys tele ++ funArgTys args+funArgTys (FACxt ctxt args) =+  ctxt ++ funArgTys args+funArgTys (FAAnon anon args) =+  anon : funArgTys args++-- | Convert a 'ForallTelescope' value into the list of 'Type's that it+-- contains. See the Haddocks for 'funArgTys' for an example of what this does.+forallTelescopeTys :: ForallTelescope -> [Type]+forallTelescopeTys (ForallVis tvbs)   = bndrParams tvbs+forallTelescopeTys (ForallInvis tvbs) = bndrParams tvbs++-- | @'filterVisFunArgsUpTo' xs args@ will split @args@ into 'VisFunArg's as+-- many times as there are elements in @xs@, pairing up each entry in @xs@ with+-- the corresponding 'VisFunArg' in the process. This will stop after the last+-- entry in @xs@ has been paired up.+--+-- For example, this:+--+-- @+-- 'filterVisFunArgsUpTo'+--   [Bool, True]+--   [ FAForalls (ForallVis [j])+--   , FAAnon j+--   , FAForalls (ForallInvis [k])+--   , FAAnon k+--   ]+-- @+--+-- Will yield:+--+-- @+-- ( [(Bool, VisFADep j), (True, VisFAAnon j)]+-- , [FAForalls (ForallInvis [k]), FAAnon k]+-- )+-- @+--+-- This function assumes the precondition that there are at least as many+-- visible function arguments in @args@ as there are elements in @xs@. If this+-- is not the case, this function will raise an error.+filterVisFunArgsUpTo :: forall a. [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)+filterVisFunArgsUpTo = go_fun_args+  where+    go_fun_args :: [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)+    go_fun_args [] args =+      ([], args)+    go_fun_args (_:_) FANil =+      error "filterVisFunArgsUpTo.go_fun_args: Too few FunArgs"+    go_fun_args xs (FACxt _ args) =+      go_fun_args xs args+    go_fun_args (x:xs) (FAAnon t args) =+      let (xs', args') = go_fun_args xs args in+      ((x, VisFAAnon t):xs', args')+    go_fun_args xs (FAForalls tele args) =+      case tele of+        ForallVis tvbs ->+          go_vis_tvbs tvbs xs args+        ForallInvis _ ->+          go_fun_args xs args++    go_vis_tvbs :: [TyVarBndrUnit] -> [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)+    go_vis_tvbs [] xs args =+      go_fun_args xs args+    go_vis_tvbs (tvb:tvbs) (x:xs) args =+      let (xs', args') = go_vis_tvbs tvbs xs args in+      ((x, VisFADep tvb):xs', args')+    go_vis_tvbs tvbs [] args =+      ([], FAForalls (ForallVis tvbs) args)++-- | @'unravelKindUpTo' xs k@ will split the function kind @k@ into its argument+-- kinds @args@ and result kind @res@, and then it will call+-- @'filterVisFunArgsUpTo' xs args@. The leftover arguments that were not split+-- apart by 'filterVisFunArgsUpTo' are then raveled back into @res@.+--+-- For example, this:+--+-- @+-- 'filterVisFunArgsUpTo'+--   [Bool, True]+--   (forall j -> j -> forall k. k -> Type)+-- @+--+-- Will yield:+--+-- @+-- ( [(Bool, VisFADep j), (True, VisFAAnon j)]+-- , forall k. k -> Type+-- )+-- @+--+-- This function assumes the precondition that there are at least as many+-- visible function arguments in @args@ as there are elements in @xs@. If this+-- is not the case, this function will raise an error.+unravelKindUpTo :: [a] -> Kind -> ([(a, VisFunArg)], Kind)+unravelKindUpTo xs k = (xs', ravelType args' res)+  where+    (args, res) = unravelType k+    (xs', args') = filterVisFunArgsUpTo xs args++-- | Resolve any infix type application in a type using the fixities that+-- are currently available. Starting in `template-haskell-2.11` types could+-- contain unresolved infix applications.+resolveInfixT :: Type -> Q Type++resolveInfixT (ForallT vs cx t) = ForallT <$> traverse (traverseTVKind resolveInfixT) vs+                                          <*> mapM resolveInfixT cx+                                          <*> resolveInfixT t+resolveInfixT (f `AppT` x)      = resolveInfixT f `appT` resolveInfixT x+resolveInfixT (ParensT t)       = resolveInfixT t+resolveInfixT (InfixT l o r)    = conT o `appT` resolveInfixT l `appT` resolveInfixT r+resolveInfixT (SigT t k)        = SigT <$> resolveInfixT t <*> resolveInfixT k+resolveInfixT t@UInfixT{}       = resolveInfixT =<< resolveInfixT1 (gatherUInfixT t)+#if MIN_VERSION_template_haskell(2,15,0)+resolveInfixT (f `AppKindT` x)  = appKindT (resolveInfixT f) (resolveInfixT x)+resolveInfixT (ImplicitParamT n t)+                                = implicitParamT n $ resolveInfixT t+#endif+#if MIN_VERSION_template_haskell(2,16,0)+resolveInfixT (ForallVisT vs t) = ForallVisT <$> traverse (traverseTVKind resolveInfixT) vs+                                             <*> resolveInfixT t+#endif+#if MIN_VERSION_template_haskell(2,19,0)+resolveInfixT (PromotedInfixT l o r)+                                = promotedT o `appT` resolveInfixT l `appT` resolveInfixT r+resolveInfixT t@PromotedUInfixT{}+                                = resolveInfixT =<< resolveInfixT1 (gatherUInfixT t)+#endif+resolveInfixT t                 = return t++gatherUInfixT :: Type -> InfixList+gatherUInfixT (UInfixT l o r)         = ilAppend (gatherUInfixT l) o False (gatherUInfixT r)+#if MIN_VERSION_template_haskell(2,19,0)+gatherUInfixT (PromotedUInfixT l o r) = ilAppend (gatherUInfixT l) o True  (gatherUInfixT r)+#endif+gatherUInfixT t = ILNil t++-- This can fail due to incompatible fixities+resolveInfixT1 :: InfixList -> TypeQ+resolveInfixT1 = go []+  where+    go :: [(Type,Name,Bool,Fixity)] -> InfixList -> TypeQ+    go ts (ILNil u) = return (foldl (\acc (l,o,p,_) -> mkConT p o `AppT` l `AppT` acc) u ts)+    go ts (ILCons l o p r) =+      do ofx <- fromMaybe defaultFixity <$> reifyFixityCompat o+         let push = go ((l,o,p,ofx):ts) r+         case ts of+           (l1,o1,p1,o1fx):ts' ->+             case compareFixity o1fx ofx of+               Just True  -> go ((mkConT p1 o1 `AppT` l1 `AppT` l, o, p, ofx):ts') r+               Just False -> push+               Nothing    -> fail (precedenceError o1 o1fx o ofx)+           _ -> push++    mkConT :: Bool -> Name -> Type+    mkConT promoted = if promoted then PromotedT else ConT++    compareFixity :: Fixity -> Fixity -> Maybe Bool+    compareFixity (Fixity n1 InfixL) (Fixity n2 InfixL) = Just (n1 >= n2)+    compareFixity (Fixity n1 InfixR) (Fixity n2 InfixR) = Just (n1 >  n2)+    compareFixity (Fixity n1 _     ) (Fixity n2 _     ) =+      case compare n1 n2 of+        GT -> Just True+        LT -> Just False+        EQ -> Nothing++    precedenceError :: Name -> Fixity -> Name -> Fixity -> String+    precedenceError o1 ofx1 o2 ofx2 =+      "Precedence parsing error: cannot mix ‘" +++      nameBase o1 ++ "’ [" ++ showFixity ofx1 ++ "] and ‘" +++      nameBase o2 ++ "’ [" ++ showFixity ofx2 +++      "] in the same infix type expression"++data InfixList+  = ILCons Type      -- The first argument to the type operator+           Name      -- The name of the infix type operator+           Bool      -- 'True' if this is a promoted infix data constructor,+                     -- 'False' otherwise+           InfixList -- The rest of the infix applications to resolve+  | ILNil Type++ilAppend :: InfixList -> Name -> Bool -> InfixList -> InfixList+ilAppend (ILNil l)            o p r = ILCons l o p r+ilAppend (ILCons l1 o1 p1 r1) o p r = ILCons l1 o1 p1 (ilAppend r1 o p r)+++-- | Render a 'Fixity' as it would appear in Haskell source.+--+-- Example: @infixl 5@+showFixity :: Fixity -> String+showFixity (Fixity n d) = showFixityDirection d ++ " " ++ show n+++-- | Render a 'FixityDirection' like it would appear in Haskell source.+--+-- Examples: @infixl@ @infixr@ @infix@+showFixityDirection :: FixityDirection -> String+showFixityDirection InfixL = "infixl"+showFixityDirection InfixR = "infixr"+showFixityDirection InfixN = "infix"++takeFieldNames :: [(Name,a,b)] -> [Name]+takeFieldNames xs = [a | (a,_,_) <- xs]++takeFieldStrictness :: [(a,Bang,b)] -> [FieldStrictness]+takeFieldStrictness xs = [normalizeStrictness a | (_,a,_) <- xs]++takeFieldTypes :: [(a,b,Type)] -> [Type]+takeFieldTypes xs = [a | (_,_,a) <- xs]++conHasRecord :: Name -> ConstructorInfo -> Bool+conHasRecord recName info =+  case constructorVariant info of+    NormalConstructor        -> False+    InfixConstructor         -> False+    RecordConstructor fields -> recName `elem` fields++------------------------------------------------------------------------++-- | Add universal quantifier for all free variables in the type. This is+-- useful when constructing a type signature for a declaration.+-- This code is careful to ensure that the order of the variables quantified+-- is determined by their order of appearance in the type signature. (In+-- contrast with being dependent upon the Ord instance for 'Name')+quantifyType :: Type -> Type+quantifyType t+  | null tvbs+  = t+  | ForallT tvbs' ctxt' t' <- t -- Collapse two consecutive foralls (#63)+  = ForallT (tvbs ++ tvbs') ctxt' t'+  | otherwise+  = ForallT tvbs [] t+  where+    tvbs = changeTVFlags SpecifiedSpec $ freeVariablesWellScoped [t]++-- | Take a list of 'Type's, find their free variables, and sort them+-- according to dependency order.+--+-- As an example of how this function works, consider the following type:+--+-- @+-- Proxy (a :: k)+-- @+--+-- Calling 'freeVariables' on this type would yield @[a, k]@, since that is+-- the order in which those variables appear in a left-to-right fashion. But+-- this order does not preserve the fact that @k@ is the kind of @a@. Moreover,+-- if you tried writing the type @forall a k. Proxy (a :: k)@, GHC would reject+-- this, since GHC would demand that @k@ come before @a@.+--+-- 'freeVariablesWellScoped' orders the free variables of a type in a way that+-- preserves this dependency ordering. If one were to call+-- 'freeVariablesWellScoped' on the type above, it would return+-- @[k, (a :: k)]@. (This is why 'freeVariablesWellScoped' returns a list of+-- 'TyVarBndr's instead of 'Name's, since it must make it explicit that @k@+-- is the kind of @a@.)+--+-- 'freeVariablesWellScoped' guarantees the free variables returned will be+-- ordered such that:+--+-- 1. Whenever an explicit kind signature of the form @(A :: K)@ is+--    encountered, the free variables of @K@ will always appear to the left of+--    the free variables of @A@ in the returned result.+--+-- 2. The constraint in (1) notwithstanding, free variables will appear in+--    left-to-right order of their original appearance.+--+-- On older GHCs, this takes measures to avoid returning explicitly bound+-- kind variables, which was not possible before @TypeInType@.+freeVariablesWellScoped :: [Type] -> [TyVarBndrUnit]+freeVariablesWellScoped tys =+  let fvs :: [Name]+      fvs = freeVariables tys++      varKindSigs :: Map Name Kind+      varKindSigs = foldMap go_ty tys+        where+          go_ty :: Type -> Map Name Kind+          go_ty (ForallT tvbs ctxt t) =+            foldr (\tvb -> Map.delete (tvName tvb))+                  (foldMap go_ty ctxt `mappend` go_ty t) tvbs+          go_ty (AppT t1 t2) = go_ty t1 `mappend` go_ty t2+          go_ty (SigT t k) =+            let kSigs = go_ty k+            in case t of+                 VarT n -> Map.insert n k kSigs+                 _      -> go_ty t `mappend` kSigs+#if MIN_VERSION_template_haskell(2,15,0)+          go_ty (AppKindT t k) = go_ty t `mappend` go_ty k+          go_ty (ImplicitParamT _ t) = go_ty t+#endif+#if MIN_VERSION_template_haskell(2,16,0)+          go_ty (ForallVisT tvbs t) =+            foldr (\tvb -> Map.delete (tvName tvb)) (go_ty t) tvbs+#endif+          go_ty _ = mempty++      -- | Do a topological sort on a list of tyvars,+      --   so that binders occur before occurrences+      -- E.g. given  [ a::k, k::*, b::k ]+      -- it'll return a well-scoped list [ k::*, a::k, b::k ]+      --+      -- This is a deterministic sorting operation+      -- (that is, doesn't depend on Uniques).+      --+      -- It is also meant to be stable: that is, variables should not+      -- be reordered unnecessarily.+      scopedSort :: [Name] -> [Name]+      scopedSort = go [] []++      go :: [Name]     -- already sorted, in reverse order+         -> [Set Name] -- each set contains all the variables which must be placed+                       -- before the tv corresponding to the set; they are accumulations+                       -- of the fvs in the sorted tvs' kinds++                       -- This list is in 1-to-1 correspondence with the sorted tyvars+                       -- INVARIANT:+                       --   all (\tl -> all (`isSubsetOf` head tl) (tail tl)) (tails fv_list)+                       -- That is, each set in the list is a superset of all later sets.+         -> [Name]     -- yet to be sorted+         -> [Name]+      go acc _fv_list [] = reverse acc+      go acc  fv_list (tv:tvs)+        = go acc' fv_list' tvs+        where+          (acc', fv_list') = insert tv acc fv_list++      insert :: Name       -- var to insert+             -> [Name]     -- sorted list, in reverse order+             -> [Set Name] -- list of fvs, as above+             -> ([Name], [Set Name])   -- augmented lists+      insert tv []     []         = ([tv], [kindFVSet tv])+      insert tv (a:as) (fvs:fvss)+        | tv `Set.member` fvs+        , (as', fvss') <- insert tv as fvss+        = (a:as', fvs `Set.union` fv_tv : fvss')++        | otherwise+        = (tv:a:as, fvs `Set.union` fv_tv : fvs : fvss)+        where+          fv_tv = kindFVSet tv++         -- lists not in correspondence+      insert _ _ _ = error "scopedSort"++      kindFVSet n =+        maybe Set.empty (Set.fromList . freeVariables) (Map.lookup n varKindSigs)+      ascribeWithKind n =+        maybe (plainTV n) (kindedTV n) (Map.lookup n varKindSigs)++  in map ascribeWithKind $ scopedSort fvs++-- | Substitute all of the free variables in a type with fresh ones+freshenFreeVariables :: Type -> Q Type+freshenFreeVariables t =+  do let xs = [ (n, VarT <$> newName (nameBase n)) | n <- freeVariables t]+     subst <- T.sequence (Map.fromList xs)+     return (applySubstitution subst t)+++-- | Class for types that support type variable substitution.+class TypeSubstitution a where+  -- | Apply a type variable substitution.+  applySubstitution :: Map Name Type -> a -> a+  -- | Compute the free type variables+  freeVariables     :: a -> [Name]++instance TypeSubstitution a => TypeSubstitution [a] where+  freeVariables     = nub . concat . map freeVariables+  applySubstitution = fmap . applySubstitution++instance TypeSubstitution Type where+  applySubstitution subst = go+    where+      go (ForallT tvs context t) =+        let (subst', tvs') = substTyVarBndrs subst tvs in+        ForallT tvs'+                (applySubstitution subst' context)+                (applySubstitution subst' t)+      go (AppT f x)      = AppT (go f) (go x)+      go (SigT t k)      = SigT (go t) (applySubstitution subst k) -- k could be Kind+      go (VarT v)        = Map.findWithDefault (VarT v) v subst+      go (InfixT l c r)  = InfixT (go l) c (go r)+      go (UInfixT l c r) = UInfixT (go l) c (go r)+      go (ParensT t)     = ParensT (go t)+#if MIN_VERSION_template_haskell(2,15,0)+      go (AppKindT t k)  = AppKindT (go t) (go k)+      go (ImplicitParamT n t)+                         = ImplicitParamT n (go t)+#endif+#if MIN_VERSION_template_haskell(2,16,0)+      go (ForallVisT tvs t) =+        let (subst', tvs') = substTyVarBndrs subst tvs in+        ForallVisT tvs'+                   (applySubstitution subst' t)+#endif+#if MIN_VERSION_template_haskell(2,19,0)+      go (PromotedInfixT l c r)+                         = PromotedInfixT (go l) c (go r)+      go (PromotedUInfixT l c r)+                         = PromotedUInfixT (go l) c (go r)+#endif+      go t               = t++      subst_tvbs :: [TyVarBndr_ flag] -> (Map Name Type -> a) -> a+      subst_tvbs tvs k = k $ foldl' (flip Map.delete) subst (map tvName tvs)++  freeVariables t =+    case t of+      ForallT tvs context t' ->+          fvs_under_forall tvs (freeVariables context `union` freeVariables t')+      AppT f x      -> freeVariables f `union` freeVariables x+      SigT t' k     -> freeVariables t' `union` freeVariables k+      VarT v        -> [v]+      InfixT l _ r  -> freeVariables l `union` freeVariables r+      UInfixT l _ r -> freeVariables l `union` freeVariables r+      ParensT t'    -> freeVariables t'+#if MIN_VERSION_template_haskell(2,15,0)+      AppKindT t k  -> freeVariables t `union` freeVariables k+      ImplicitParamT _ t+                    -> freeVariables t+#endif+#if MIN_VERSION_template_haskell(2,16,0)+      ForallVisT tvs t'+                    -> fvs_under_forall tvs (freeVariables t')+#endif+#if MIN_VERSION_template_haskell(2,19,0)+      PromotedInfixT l _ r+                    -> freeVariables l `union` freeVariables r+      PromotedUInfixT l _ r+                    -> freeVariables l `union` freeVariables r+#endif+      _             -> []+    where+      fvs_under_forall :: [TyVarBndr_ flag] -> [Name] -> [Name]+      fvs_under_forall tvs fvs =+        (freeVariables (map tvKind tvs) `union` fvs)+        \\ map tvName tvs++instance TypeSubstitution ConstructorInfo where+  freeVariables ci =+      (freeVariables (map tvKind (constructorVars ci))+          `union` freeVariables (constructorContext ci)+          `union` freeVariables (constructorFields ci))+      \\ (tvName <$> constructorVars ci)++  applySubstitution subst ci =+    let subst' = foldl' (flip Map.delete) subst (map tvName (constructorVars ci)) in+    ci { constructorVars    = map (mapTVKind (applySubstitution subst'))+                                  (constructorVars ci)+       , constructorContext = applySubstitution subst' (constructorContext ci)+       , constructorFields  = applySubstitution subst' (constructorFields ci)+       }++-- | Substitutes into the kinds of type variable binders. This makes an effort+-- to avoid capturing the 'TyVarBndr' names during substitution by+-- alpha-renaming names if absolutely necessary. For a version of this function+-- which does /not/ avoid capture, see 'substTyVarBndrKinds'.+substTyVarBndrs :: Map Name Type -> [TyVarBndr_ flag] -> (Map Name Type, [TyVarBndr_ flag])+substTyVarBndrs = mapAccumL substTyVarBndr++-- | The workhorse for 'substTyVarBndrs'.+substTyVarBndr :: Map Name Type -> TyVarBndr_ flag -> (Map Name Type, TyVarBndr_ flag)+substTyVarBndr subst tvb+  | tvbName `Map.member` subst+  = (Map.delete tvbName subst, mapTVKind (applySubstitution subst) tvb)+  | tvbName `Set.notMember` substRangeFVs+  = (subst, mapTVKind (applySubstitution subst) tvb)+  | otherwise+  = let tvbName' = evade tvbName in+    ( Map.insert tvbName (VarT tvbName') subst+    , mapTV (\_ -> tvbName') id (applySubstitution subst) tvb+    )+  where+    tvbName :: Name+    tvbName = tvName tvb++    substRangeFVs :: Set Name+    substRangeFVs = Set.fromList $ freeVariables $ Map.elems subst++    evade :: Name -> Name+    evade n | n `Set.member` substRangeFVs+            = evade $ bump n+            | otherwise+            = n++    -- An improvement would be to try a variety of different characters instead+    -- of prepending the same character repeatedly. Let's wait to see if+    -- someone complains about this before making this more complicated,+    -- however.+    bump :: Name -> Name+    bump n = mkName $ 'f':nameBase n++-- | Substitutes into the kinds of type variable binders. This is slightly more+-- efficient than 'substTyVarBndrs', but at the expense of not avoiding+-- capture. Only use this function in situations where you know that none of+-- the 'TyVarBndr' names are contained in the range of the substitution.+substTyVarBndrKinds :: Map Name Type -> [TyVarBndr_ flag] -> [TyVarBndr_ flag]+substTyVarBndrKinds subst = map (substTyVarBndrKind subst)++-- | The workhorse for 'substTyVarBndrKinds'.+substTyVarBndrKind :: Map Name Type -> TyVarBndr_ flag -> TyVarBndr_ flag+substTyVarBndrKind subst = mapTVKind (applySubstitution subst)++------------------------------------------------------------------------++combineSubstitutions :: Map Name Type -> Map Name Type -> Map Name Type+combineSubstitutions x y = Map.union (fmap (applySubstitution y) x) y++-- | Compute the type variable substitution that unifies a list of types,+-- or fail in 'Q'.+--+-- All infix issue should be resolved before using 'unifyTypes'+--+-- Alpha equivalent quantified types are not unified.+unifyTypes :: [Type] -> Q (Map Name Type)+unifyTypes [] = return Map.empty+unifyTypes (t:ts) =+  do t':ts' <- mapM resolveTypeSynonyms (t:ts)+     let aux sub u =+           do sub' <- unify' (applySubstitution sub t')+                             (applySubstitution sub u)+              return (combineSubstitutions sub sub')++     case foldM aux Map.empty ts' of+       Right m -> return m+       Left (x,y) ->+         fail $ showString "Unable to unify types "+              . showsPrec 11 x+              . showString " and "+              . showsPrec 11 y+              $ ""++unify' :: Type -> Type -> Either (Type,Type) (Map Name Type)++unify' (VarT n) (VarT m) | n == m = pure Map.empty+unify' (VarT n) t | n `elem` freeVariables t = Left (VarT n, t)+                  | otherwise                = Right (Map.singleton n t)+unify' t (VarT n) | n `elem` freeVariables t = Left (VarT n, t)+                  | otherwise                = Right (Map.singleton n t)++unify' (AppT f1 x1) (AppT f2 x2) =+  do sub1 <- unify' f1 f2+     sub2 <- unify' (applySubstitution sub1 x1) (applySubstitution sub1 x2)+     Right (combineSubstitutions sub1 sub2)++-- Doesn't unify kind signatures+unify' (SigT t _) u = unify' t u+unify' t (SigT u _) = unify' t u++-- only non-recursive cases should remain at this point+unify' t u+  | t == u    = Right Map.empty+  | otherwise = Left (t,u)+++-- | Construct an equality constraint. The implementation of 'Pred' varies+-- across versions of Template Haskell.+equalPred :: Type -> Type -> Pred+equalPred x y = AppT (AppT EqualityT x) y++-- | Construct a typeclass constraint. The implementation of 'Pred' varies+-- across versions of Template Haskell.+classPred :: Name {- ^ class -} -> [Type] {- ^ parameters -} -> Pred+classPred = foldl AppT . ConT++-- | Match a 'Pred' representing an equality constraint. Returns+-- arguments to the equality constraint if successful.+asEqualPred :: Pred -> Maybe (Type,Type)+asEqualPred (EqualityT `AppT` x `AppT` y)                    = Just (x,y)+asEqualPred (ConT eq   `AppT` x `AppT` y) | eq == eqTypeName = Just (x,y)+asEqualPred _                                                = Nothing++-- | Match a 'Pred' representing a class constraint.+-- Returns the classname and parameters if successful.+asClassPred :: Pred -> Maybe (Name, [Type])+asClassPred t =+  case decomposeType t of+    ConT f :| xs | f /= eqTypeName -> Just (f,xs)+    _                              -> Nothing++------------------------------------------------------------------------++-- | If we are working with a 'Dec' obtained via 'reify' (as opposed to one+-- created from, say, [d| ... |] quotes), then we need to apply more hacks than+-- we otherwise would to sanitize the 'Dec'. See #28.+type IsReifiedDec = Bool++isReified, isn'tReified :: IsReifiedDec+isReified    = True+isn'tReified = False++-- On old versions of GHC, reify would not give you kind signatures for+-- GADT type variables of kind *. To work around this, we insert the kinds+-- manually on any reified type variable binders without a signature. However,+-- don't do this for quoted type variable binders (#84).++giveDIVarsStarKinds :: IsReifiedDec -> DatatypeInfo -> DatatypeInfo+giveDIVarsStarKinds isReified info =+  info { datatypeVars      = map (giveTyVarBndrStarKind isReified) (datatypeVars info)+       , datatypeInstTypes = map (giveTypeStarKind isReified) (datatypeInstTypes info) }++giveCIVarsStarKinds :: IsReifiedDec -> ConstructorInfo -> ConstructorInfo+giveCIVarsStarKinds isReified info =+  info { constructorVars = map (giveTyVarBndrStarKind isReified) (constructorVars info) }++giveTyVarBndrStarKind :: IsReifiedDec ->  TyVarBndrUnit -> TyVarBndrUnit+giveTyVarBndrStarKind isReified tvb+  | isReified+  = elimTV (\n -> kindedTV n starK) (\_ _ -> tvb) tvb+  | otherwise+  = tvb++giveTypeStarKind :: IsReifiedDec -> Type -> Type+giveTypeStarKind isReified t+  | isReified+  = case t of+      VarT n -> SigT t starK+      _      -> t+  | otherwise+  = t++-- | Prior to GHC 8.2.1, reify was broken for data instances and newtype+-- instances. This code attempts to detect the problem and repair it if+-- possible.+--+-- The particular problem is that the type variables used in the patterns+-- while defining a data family instance do not completely match those+-- used when defining the fields of the value constructors beyond the+-- base names. This code attempts to recover the relationship between the+-- type variables.+--+-- It is possible, however, to generate these kinds of declarations by+-- means other than reify. In these cases the name bases might not be+-- unique and the declarations might be well formed. In such a case this+-- code attempts to avoid altering the declaration.+--+-- https://ghc.haskell.org/trac/ghc/ticket/13618+repair13618 :: DatatypeInfo -> Q DatatypeInfo+repair13618 info =+  do s <- T.sequence (Map.fromList substList)+     return info { datatypeCons = applySubstitution s (datatypeCons info) }++  where+    used  = freeVariables (datatypeCons info)+    bound = map tvName (datatypeVars info)+    free  = used \\ bound++    substList =+      [ (u, substEntry u vs)+      | u <- free+      , let vs = [v | v <- bound, nameBase v == nameBase u]+      ]++    substEntry _ [v] = varT v+    substEntry u []  = fail ("Impossible free variable: " ++ show u)+    substEntry u _   = fail ("Ambiguous free variable: "  ++ show u)++------------------------------------------------------------------------++-- | Backward compatible version of 'dataD'+dataDCompat ::+  CxtQ           {- ^ context                 -} ->+  Name           {- ^ type constructor        -} ->+  [TyVarBndrVis] {- ^ type parameters         -} ->+  [ConQ]         {- ^ constructor definitions -} ->+  [Name]         {- ^ derived class names     -} ->+  DecQ+#if MIN_VERSION_template_haskell(2,12,0)+dataDCompat c n ts cs ds =+  dataD c n ts Nothing cs+    (if null ds then [] else [derivClause Nothing (map conT ds)])+#else+dataDCompat c n ts cs ds =+  dataD c n ts Nothing cs+    (return (map ConT ds))+#endif++-- | Backward compatible version of 'newtypeD'+newtypeDCompat ::+  CxtQ           {- ^ context                 -} ->+  Name           {- ^ type constructor        -} ->+  [TyVarBndrVis] {- ^ type parameters         -} ->+  ConQ           {- ^ constructor definition  -} ->+  [Name]         {- ^ derived class names     -} ->+  DecQ+#if MIN_VERSION_template_haskell(2,12,0)+newtypeDCompat c n ts cs ds =+  newtypeD c n ts Nothing cs+    (if null ds then [] else [derivClause Nothing (map conT ds)])+#else+newtypeDCompat c n ts cs ds =+  newtypeD c n ts Nothing cs+    (return (map ConT ds))+#endif++-- | Backward compatible version of 'tySynInstD'+tySynInstDCompat ::+  Name                    {- ^ type family name    -}   ->+  Maybe [Q TyVarBndrUnit] {- ^ type variable binders -} ->+  [TypeQ]                 {- ^ instance parameters -}   ->+  TypeQ                   {- ^ instance result     -}   ->+  DecQ+#if MIN_VERSION_template_haskell(2,15,0)+tySynInstDCompat n mtvbs ps r = TySynInstD <$> (TySynEqn <$> mapM sequence mtvbs+                                                         <*> foldl' appT (conT n) ps+                                                         <*> r)+#else+tySynInstDCompat n _ ps r     = TySynInstD n <$> (TySynEqn <$> sequence ps <*> r)+#endif++-- | Backward compatible version of 'pragLineD'. Returns+-- 'Nothing' if line pragmas are not suported.+pragLineDCompat ::+  Int     {- ^ line number -} ->+  String  {- ^ file name   -} ->+  Maybe DecQ+pragLineDCompat ln fn = Just (pragLineD ln fn)++arrowKCompat :: Kind -> Kind -> Kind+arrowKCompat x y = arrowK `appK` x `appK` y++------------------------------------------------------------------------++-- | Backwards compatibility wrapper for 'Fixity' lookup.+--+-- In @template-haskell-2.11.0.0@ and later, the answer will always+-- be 'Just' of a fixity.+--+-- Before @template-haskell-2.11.0.0@ it was only possible to determine+-- fixity information for variables, class methods, and data constructors.+-- In this case for type operators the answer could be 'Nothing', which+-- indicates that the answer is unavailable.+reifyFixityCompat :: Name -> Q (Maybe Fixity)+reifyFixityCompat n = recover (return Nothing) ((`mplus` Just defaultFixity) <$> reifyFixity n)  -- | Call 'reify' and return @'Just' info@ if successful or 'Nothing' if -- reification failed.
src/Language/Haskell/TH/Datatype/Internal.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE TemplateHaskellQuotes #-}  #if MIN_VERSION_template_haskell(2,12,0) {-# Language Safe #-}-#elif __GLASGOW_HASKELL__ >= 702+#else {-# Language Trustworthy #-} #endif @@ -20,13 +21,13 @@  import Language.Haskell.TH.Syntax +#if MIN_VERSION_base(4,13,0)+import Data.Type.Equality+#endif+ eqTypeName :: Name-#if MIN_VERSION_base(4,9,0) && !(MIN_VERSION_base(4,13,0))-eqTypeName = mkNameG_tc "base" "Data.Type.Equality" "~"+#if MIN_VERSION_base(4,13,0)+eqTypeName = ''(~) #else-eqTypeName = mkNameG_tc "ghc-prim" "GHC.Types" "~"+eqTypeName = mkNameG_tc "base" "Data.Type.Equality" "~" #endif---- This is only needed for GHC 7.6-specific bug-starKindName :: Name-starKindName = mkNameG_tc "ghc-prim" "GHC.Prim" "*"
src/Language/Haskell/TH/Datatype/TyVarBndr.hs view
@@ -1,13 +1,8 @@-{-# Language CPP, DeriveDataTypeable #-}--#if MIN_VERSION_base(4,4,0)-#define HAS_GENERICS-{-# Language DeriveGeneric #-}-#endif+{-# Language CPP, DeriveDataTypeable, DeriveGeneric, DeriveLift, PatternSynonyms, ViewPatterns #-}  #if MIN_VERSION_template_haskell(2,12,0) {-# Language Safe #-}-#elif __GLASGOW_HASKELL__ >= 702+#else {-# Language Trustworthy #-} #endif @@ -28,7 +23,16 @@     TyVarBndr_   , TyVarBndrUnit   , TyVarBndrSpec+  , TyVarBndrVis   , Specificity(..)+#if __GLASGOW_HASKELL__ >= 907+  , BndrVis(..)+#else+  , BndrVis+  , pattern BndrReq+  , pattern BndrInvis+#endif+  , DefaultBndrFlag(..)      -- * Constructing @TyVarBndr@s     -- ** @flag@-polymorphic@@ -42,13 +46,23 @@   , plainTVSpecified   , kindedTVInferred   , kindedTVSpecified+    -- ** @TyVarBndrVis@+  , plainTVReq+  , plainTVInvis+  , kindedTVReq+  , kindedTVInvis      -- * Constructing @Specificity@   , inferredSpec   , specifiedSpec +    -- * Constructing @BndrVis@+  , bndrReq+  , bndrInvis+     -- * Modifying @TyVarBndr@s   , elimTV+  , elimTVFlag   , mapTV   , mapTVName   , mapTVFlag@@ -66,44 +80,39 @@     -- * Properties of @TyVarBndr@s   , tvName   , tvKind+  , tvFlag   ) where  import Control.Applicative import Control.Monad-import Data.Data (Typeable, Data)+import Data.Data (Data)+import GHC.Generics (Generic) import Language.Haskell.TH.Lib import Language.Haskell.TH.Syntax -#ifdef HAS_GENERICS-import GHC.Generics (Generic)-#endif- -- | A type synonym for 'TyVarBndr'. This is the recommended way to refer to -- 'TyVarBndr's if you wish to achieve backwards compatibility with older -- versions of @template-haskell@, where 'TyVarBndr' lacked a @flag@ type--- parameter representing its specificity (if it has one).+-- parameter (if it has one). #if MIN_VERSION_template_haskell(2,17,0) type TyVarBndr_ flag = TyVarBndr flag #else type TyVarBndr_ flag = TyVarBndr --- | A 'TyVarBndr' where the specificity is irrelevant. This is used for--- 'TyVarBndr's that do not interact with visible type application.+-- | A 'TyVarBndr' without a flag. This is used for 'TyVarBndr's that do not+-- interact with visible type application and are not binders for type-level+-- declarations. type TyVarBndrUnit = TyVarBndr --- | A 'TyVarBndr' with an explicit 'Specificity'. This is used for--- 'TyVarBndr's that interact with visible type application.+-- | A 'TyVarBndr' with a 'Specificity' flag. This is used for 'TyVarBndr's that+-- interact with visible type application. type TyVarBndrSpec = TyVarBndr  -- | Determines how a 'TyVarBndr' interacts with visible type application. data Specificity   = SpecifiedSpec -- ^ @a@. Eligible for visible type application.   | InferredSpec  -- ^ @{a}@. Not eligible for visible type application.-  deriving (Show, Eq, Ord, Typeable, Data-#ifdef HAS_GENERICS-           ,Generic-#endif-           )+  deriving (Show, Eq, Ord, Data, Generic, Lift)  inferredSpec :: Specificity inferredSpec = InferredSpec@@ -112,6 +121,75 @@ specifiedSpec = SpecifiedSpec #endif +#if !MIN_VERSION_template_haskell(2,21,0)+-- | A 'TyVarBndr' with a 'BndrVis' flag. This is used for 'TyVarBndr's in+-- type-level declarations (e.g., the binders in @data D \@k (a :: k)@).+type TyVarBndrVis = TyVarBndr_ BndrVis++-- | Because pre-9.8 GHCs do not support invisible binders in type-level+-- declarations, we simply make 'BndrVis' an alias for @()@ as a compatibility+-- shim for old GHCs. This matches how type-level 'TyVarBndr's were flagged+-- prior to GHC 9.8.+type BndrVis = ()+#if __GLASGOW_HASKELL__ >= 802+{-# COMPLETE BndrReq, BndrInvis #-}+#endif++-- | Because pre-9.8 GHCs do not support invisible binders in type-level+-- declarations, we simply make 'BndrReq' a pattern synonym for @()@ as a+-- compatibility shim for old GHCs. This matches how type-level 'TyVarBndr's+-- were flagged prior to GHC 9.8.+pattern BndrReq :: BndrVis+pattern BndrReq = ()++-- | Because pre-9.8 GHCs do not support invisible binders in type-level+-- declarations, this compatibility shim is defined in a somewhat unusual way:+--+-- * As a pattern, 'BndrInvis' will never match on pre-9.8 GHCs. That way, if+--   you write pattern matches like this:+--+--   @+--   case flag of+--     'BndrInvis' -> ...+--     'BndrVis' -> ...+--   @+--+--   Then the first branch will never be taken on pre-9.8 GHCs.+--+-- * 'BndrInvis' is a unidirectional pattern synonym on pre-9.8 GHCs, so it+--   cannot be used as an expression on these GHC versions. This is done in an+--   effort to avoid pitfalls that could occur if 'BndrInvis' were defined like+--   so:+--+--   @+--   pattern 'BndrInvis' = ()+--   @+--+--   If this were the definition, then a user could write code involving+--   'BndrInvis' that would construct an invisible type-level binder on GHC 9.8+--   or later, but a /visible/ type-level binder on older GHCs! This would be+--   disastrous, so we prevent the user from doing such a thing.+pattern BndrInvis :: BndrVis+pattern BndrInvis <- ((\() -> True) -> False)++bndrReq :: BndrVis+bndrReq = ()++bndrInvis :: BndrVis+bndrInvis = ()++-- | A class characterizing reasonable default values for various 'TyVarBndr'+-- @flag@ types.+class DefaultBndrFlag flag where+  defaultBndrFlag :: flag++instance DefaultBndrFlag () where+  defaultBndrFlag = ()++instance DefaultBndrFlag Specificity where+  defaultBndrFlag = SpecifiedSpec+#endif+ -- | Construct a 'PlainTV' with the given @flag@. plainTVFlag :: Name -> flag -> TyVarBndr_ flag #if MIN_VERSION_template_haskell(2,17,0)@@ -128,6 +206,14 @@ plainTVSpecified :: Name -> TyVarBndrSpec plainTVSpecified n = plainTVFlag n SpecifiedSpec +-- | Construct a 'PlainTV' with a 'BndrReq'.+plainTVReq :: Name -> TyVarBndrVis+plainTVReq n = plainTVFlag n bndrReq++-- | Construct a 'PlainTV' with a 'BndrInvis'.+plainTVInvis :: Name -> TyVarBndrVis+plainTVInvis n = plainTVFlag n bndrInvis+ -- | Construct a 'KindedTV' with the given @flag@. kindedTVFlag :: Name -> flag -> Kind -> TyVarBndr_ flag #if MIN_VERSION_template_haskell(2,17,0)@@ -144,6 +230,14 @@ kindedTVSpecified :: Name -> Kind -> TyVarBndrSpec kindedTVSpecified n k = kindedTVFlag n SpecifiedSpec k +-- | Construct a 'KindedTV' with a 'BndrReq'.+kindedTVReq :: Name -> Kind -> TyVarBndrVis+kindedTVReq n k = kindedTVFlag n bndrReq k++-- | Construct a 'KindedTV' with a 'BndrInvis'.+kindedTVInvis :: Name -> Kind -> TyVarBndrVis+kindedTVInvis n k = kindedTVFlag n bndrInvis k+ -- | Case analysis for a 'TyVarBndr'. If the value is a @'PlainTV' n _@, apply -- the first function to @n@; if it is @'KindedTV' n _ k@, apply the second -- function to @n@ and @k@.@@ -156,6 +250,20 @@ elimTV _ptv ktv (KindedTV n k) = ktv n k #endif +-- | Case analysis for a 'TyVarBndr' that includes @flag@s in the continuation+-- arguments. Note that 'TyVarBndr's did not include @flag@s prior to+-- @template-haskell-2.17.0.0@, so on older versions of @template-haskell@,+-- these @flag@s instead become @()@.+#if MIN_VERSION_template_haskell(2,17,0)+elimTVFlag :: (Name -> flag -> r) -> (Name -> flag -> Kind -> r) -> TyVarBndr_ flag -> r+elimTVFlag ptv _ktv (PlainTV n flag)    = ptv n flag+elimTVFlag _ptv ktv (KindedTV n flag k) = ktv n flag k+#else+elimTVFlag :: (Name -> () -> r) -> (Name -> () -> Kind -> r) -> TyVarBndr_ flag -> r+elimTVFlag ptv _ktv (PlainTV n)    = ptv n ()+elimTVFlag _ptv ktv (KindedTV n k) = ktv n () k+#endif+ -- | Map over the components of a 'TyVarBndr'. mapTV :: (Name -> Name) -> (flag -> flag') -> (Kind -> Kind)       -> TyVarBndr_ flag -> TyVarBndr_ flag'@@ -346,3 +454,14 @@ -- | Extract the kind from a 'TyVarBndr'. Assumes 'PlainTV' has kind @*@. tvKind :: TyVarBndr_ flag -> Kind tvKind = elimTV (\_ -> starK) (\_ k -> k)++-- | Extract the @flag@ from a 'TyVarBndr'. Note that 'TyVarBndr's did not+-- include @flag@s prior to @template-haskell-2.17.0.0@, so on older versions of+-- @template-haskell@, this functions instead returns @()@.+#if MIN_VERSION_template_haskell(2,17,0)+tvFlag :: TyVarBndr_ flag -> flag+tvFlag = elimTVFlag (\_ flag -> flag) (\_ flag _ -> flag)+#else+tvFlag :: TyVarBndr_ flag -> ()+tvFlag _ = ()+#endif
test/Harness.hs view
@@ -16,9 +16,6 @@   ( validateDI   , validateCI   , equateCxt--    -- * Utilities-  , varKCompat   ) where  import           Control.Monad@@ -47,11 +44,15 @@      check "datatypeVars len"      (length . datatypeVars)      dat1 dat2      check "datatypeInstTypes len" (length . datatypeInstTypes) dat1 dat2      check "datatypeVariant"       datatypeVariant              dat1 dat2-     check "datatypeCons len"      (length . datatypeCons)      dat1 dat2-      let sub = Map.fromList (zip (freeVariables (bndrParams (datatypeVars dat2)))                                  (map VarT (freeVariables (bndrParams (datatypeVars dat1)))))+     check "datatypeReturnKind"+           id+           (datatypeReturnKind dat1)+           (applySubstitution sub $ datatypeReturnKind dat2)+     check "datatypeCons len"      (length . datatypeCons)      dat1 dat2 +      check "datatypeVars" id        (datatypeVars dat1)        (substIntoTyVarBndrs sub (datatypeVars dat2))@@ -128,29 +129,9 @@  equateStrictness :: FieldStrictness -> FieldStrictness -> Either String () equateStrictness fs1 fs2 =-  check "constructorStrictness" oldGhcHack fs1 fs2-  where-#if MIN_VERSION_template_haskell(2,7,0)-    oldGhcHack = id-#else-    -- GHC 7.0 and 7.2 didn't have an Unpacked TH constructor, so as a-    -- simple workaround, we will treat unpackedAnnot as isStrictAnnot-    -- (the closest equivalent).-    oldGhcHack fs-      | fs == unpackedAnnot = isStrictAnnot-      | otherwise           = fs-#endif+  check "constructorStrictness" id fs1 fs2  check :: (Show b, Eq b) => String -> (a -> b) -> a -> a -> Either String () check lbl f x y   | f x == f y = Right ()   | otherwise  = Left (lbl ++ ":\n\n" ++ show (f x) ++ "\n\n" ++ show (f y))---- If on a recent-enough version of Template Haskell, construct a kind variable.--- Otherwise, default to starK.-varKCompat :: Name -> Kind-#if MIN_VERSION_template_haskell(2,8,0)-varKCompat = VarT-#else-varKCompat _ = starK-#endif
test/Main.hs view
@@ -1,7 +1,7 @@-{-# Language CPP, FlexibleContexts, TypeFamilies, KindSignatures, TemplateHaskell, GADTs #-}+{-# Language CPP, FlexibleContexts, TypeFamilies, KindSignatures, TemplateHaskell, GADTs, RankNTypes, MagicHash, ConstraintKinds, PolyKinds #-} -#if __GLASGOW_HASKELL__ >= 704-{-# LANGUAGE ConstraintKinds #-}+#if __GLASGOW_HASKELL__ < 806+{-# Language TypeInType #-} #endif  #if __GLASGOW_HASKELL__ >= 807@@ -9,10 +9,17 @@ {-# LANGUAGE TypeApplications #-} #endif -#if MIN_VERSION_template_haskell(2,8,0)-{-# Language PolyKinds #-}+#if MIN_VERSION_template_haskell(2,21,0)+{-# Language TypeAbstractions #-} #endif +#if MIN_VERSION_template_haskell(2,18,0)+{-# LANGUAGE UnliftedDatatypes #-}+#endif++-- We should aim to enable -Wincomplete-uni-patterns long-term. See #121.+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+ {-| Module      : Main Description : Test cases for the th-abstraction package@@ -27,19 +34,23 @@ -} module Main (main) where -#if __GLASGOW_HASKELL__ >= 704-import           Control.Monad (zipWithM_)-#endif--import           Control.Monad (unless, when)+import           Control.Monad (unless, when, zipWithM_) import qualified Data.Map as Map--#if MIN_VERSION_base(4,7,0)+import           Data.Kind import           Data.Type.Equality ((:~:)(..))++#if __GLASGOW_HASKELL__ >= 810+import           GHC.Exts (Any, RuntimeRep(..), TYPE) #endif+#if __GLASGOW_HASKELL__ >= 902+import           GHC.Exts (UnliftedType, Levity(..))+#endif -import           Language.Haskell.TH-import           Language.Haskell.TH.Datatype+import           GHC.Exts (Array#)++import qualified Language.Haskell.TH as TH (Type)+import           Language.Haskell.TH hiding (Type)+import           Language.Haskell.TH.Datatype as Datatype import           Language.Haskell.TH.Datatype.TyVarBndr import           Language.Haskell.TH.Lib (starK) @@ -59,11 +70,8 @@      voidstosTest      strictDemoTest      recordVanillaTest-#if MIN_VERSION_template_haskell(2,6,0)      t43Test      t58Test-#endif-#if MIN_VERSION_template_haskell(2,7,0)      dataFamilyTest      ghc78bugTest      quotedTest@@ -75,33 +83,22 @@      t46Test      t73Test      t95Test-#endif      fixityLookupTest-#if __GLASGOW_HASKELL__ >= 704      resolvePredSynonymsTest-#endif      reifyDatatypeWithConNameTest      reifyConstructorTest-#if MIN_VERSION_base(4,7,0)      importedEqualityTest-#endif-#if MIN_VERSION_template_haskell(2,8,0)      kindSubstTest      t59Test      t61Test      t66Test      t80Test-#endif-#if MIN_VERSION_template_haskell(2,11,0)      t79TestA-#endif #if MIN_VERSION_template_haskell(2,19,0)      t79TestB #endif-#if __GLASGOW_HASKELL__ >= 800      t37Test      polyKindedExTyvarTest-#endif #if __GLASGOW_HASKELL__ >= 807      resolveTypeSynonymsVKATest #endif@@ -110,7 +107,28 @@      t70Test      t88Test      captureAvoidanceTest+#if MIN_VERSION_template_haskell(2,20,0)+     t100Test+#endif+#if MIN_VERSION_template_haskell(2,21,0)+     t103Test+#endif+#if __GLASGOW_HASKELL__ >= 810+     t107Test+     t108Test+#endif+#if __GLASGOW_HASKELL__ >= 804+     t110Test+#endif+#if MIN_VERSION_template_haskell(2,16,0)+     unboxedTupleTest+#endif+#if MIN_VERSION_template_haskell(2,18,0)+     unliftedGADTDecTest+#endif+     primTyConTest + adt1Test :: IO () adt1Test =   $(do info <- reifyDatatype ''Adt1@@ -127,6 +145,7 @@            , datatypeVars = [aTvb,bTvb]            , datatypeInstTypes = [aSig, bSig]            , datatypeVariant = Datatype+           , datatypeReturnKind = starK            , datatypeCons =                [ ConstructorInfo                    { constructorName = 'Adtc1@@ -160,6 +179,7 @@            , datatypeVars = [kindedTV a starK]            , datatypeInstTypes = [SigT aVar starK]            , datatypeVariant = Datatype+           , datatypeReturnKind = starK            , datatypeCons =                [ ConstructorInfo                    { constructorName = 'Gadtc1@@ -207,6 +227,7 @@            , datatypeVars      = [kindedTV a starK]            , datatypeInstTypes = [SigT (VarT a) starK]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ con, con { constructorName = 'Gadtrecc2 } ]            }@@ -228,6 +249,7 @@            , datatypeVars      = [aTvb, bTvb, cTvb]            , datatypeInstTypes = [aSig, bSig, cSig]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'Equalc@@ -260,6 +282,7 @@            , datatypeVars      = []            , datatypeInstTypes = []            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'Showable@@ -282,6 +305,7 @@            , datatypeVars      = []            , datatypeInstTypes = []            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'R1@@ -317,6 +341,7 @@            , datatypeVars      = [aTvb, bTvb]            , datatypeInstTypes = [aSig, bSig]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ con { constructorName = 'Gadt2c1                      , constructorContext = [equalPred bVar (AppT ListT aVar)] }@@ -341,6 +366,7 @@            , datatypeVars      = [kindedTV g (arrowKCompat starK starK)]            , datatypeInstTypes = [SigT (VarT g) (arrowKCompat starK starK)]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      = []            }   )@@ -355,6 +381,7 @@            , datatypeVars      = []            , datatypeInstTypes = []            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'StrictDemo@@ -374,7 +401,6 @@   $(do info <- reifyRecord 'gadtrec1a        validateCI info gadtRecVanillaCI) -#if MIN_VERSION_template_haskell(2,6,0) t43Test :: IO () t43Test =   $(do [decPlain] <- [d| data T43Plain where MkT43Plain :: T43Plain |]@@ -386,6 +412,7 @@            , datatypeVars      = []            , datatypeInstTypes = []            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = mkName "MkT43Plain"@@ -405,6 +432,7 @@            , datatypeVars      = []            , datatypeInstTypes = []            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = mkName "MkT43Fam"@@ -429,6 +457,7 @@            , datatypeVars      = []            , datatypeInstTypes = []            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = mkName "MkFoo"@@ -439,9 +468,7 @@                    , constructorVariant    = NormalConstructor } ]            }    )-#endif -#if MIN_VERSION_template_haskell(2,7,0) dataFamilyTest :: IO () dataFamilyTest =   $(do info <- reifyDatatype 'DFMaybe@@ -453,6 +480,7 @@            , datatypeVars      = [kindedTV a starK]            , datatypeInstTypes = [AppT (ConT ''Maybe) (VarT a)]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'DFMaybe@@ -476,6 +504,7 @@            , datatypeVars      = [kindedTV c starK]            , datatypeInstTypes = [SigT cVar starK]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'DF1@@ -500,6 +529,7 @@            , datatypeVars      = [plainTV a]            , datatypeInstTypes = [aVar]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = mkName "MkQuoted"@@ -515,18 +545,15 @@ polyTest =   $(do info <- reifyDatatype 'MkPoly        let [a,k] = map mkName ["a","k"]-           kVar  = varKCompat k+           kVar  = VarT k        validateDI info          DatatypeInfo            { datatypeName      = ''Poly            , datatypeContext   = []-           , datatypeVars      = [-#if __GLASGOW_HASKELL__ >= 800-                                 kindedTV k starK,-#endif-                                 kindedTV a kVar ]+           , datatypeVars      = [kindedTV k starK, kindedTV a kVar]            , datatypeInstTypes = [SigT (VarT a) kVar]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'MkPoly@@ -552,6 +579,7 @@            , datatypeVars      = [cTvb,dTvb]            , datatypeInstTypes = [cSig,dSig]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'MkGadtFam1@@ -610,6 +638,7 @@            , datatypeVars      = []            , datatypeInstTypes = [ConT ''Int]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = mkName "FamLocalDec1Int"@@ -635,6 +664,7 @@            , datatypeVars      = [aTvb,bTvb]            , datatypeInstTypes = [ConT ''Int, TupleT 2 `AppT` aVar `AppT` bVar, aVar]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = mkName "FamLocalDec2Int"@@ -673,6 +703,7 @@            , datatypeVars      = [bTvb]            , datatypeInstTypes = [ConT ''Int, SigT bVar starK]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'MkT73@@ -697,6 +728,7 @@            , datatypeVars      = [aTvb]            , datatypeInstTypes = [AppT ListT aVar]            , datatypeVariant   = DataInstance+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'MkT95@@ -707,14 +739,12 @@                    , constructorVariant    = NormalConstructor }]            }    )-#endif  fixityLookupTest :: IO () fixityLookupTest =   $(do Just (Fixity 6 InfixR) <- reifyFixityCompat '(:**:)        [| return () |]) -#if __GLASGOW_HASKELL__ >= 704 resolvePredSynonymsTest :: IO () resolvePredSynonymsTest =   $(do info <- reifyDatatype ''PredSynT@@ -726,7 +756,6 @@            test3 = mkTest cxt3 [equalPred (ConT ''Int) (ConT ''Int)]        mapM_ (either fail return) [test1,test2,test3]        [| return () |])-#endif  reifyDatatypeWithConNameTest :: IO () reifyDatatypeWithConNameTest =@@ -739,6 +768,7 @@           , datatypeVars      = [kindedTV a starK]           , datatypeInstTypes = [SigT (VarT a) starK]           , datatypeVariant   = Datatype+          , datatypeReturnKind = starK           , datatypeCons      =               [ ConstructorInfo                   { constructorName       = 'Nothing@@ -758,25 +788,24 @@   $(do info <- reifyConstructor 'Just        validateCI info justCI) -#if MIN_VERSION_base(4,7,0) importedEqualityTest :: IO () importedEqualityTest =   $(do info <- reifyDatatype ''(:~:)        let names@[a,b] = map mkName ["a","b"]            [aVar,bVar] = map VarT names            k           = mkName "k"-           kKind       = varKCompat k+           kKind       = VarT k        validateDI info          DatatypeInfo            { datatypeContext   = []            , datatypeName      = ''(:~:)-           , datatypeVars      = [-#if __GLASGOW_HASKELL__ >= 800-                                 kindedTV k starK,-#endif-                                 kindedTV a kKind, kindedTV b kKind]+           , datatypeVars      = [ kindedTV k starK+                                 , kindedTV a kKind+                                 , kindedTV b kKind+                                 ]            , datatypeInstTypes = [SigT aVar kKind, SigT bVar kKind]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'Refl@@ -787,9 +816,7 @@                    , constructorVariant    = NormalConstructor } ]            }    )-#endif -#if MIN_VERSION_template_haskell(2,8,0) kindSubstTest :: IO () kindSubstTest =   $(do k1 <- newName "k1"@@ -798,7 +825,7 @@        let ty = ForallT [kindedTVSpecified a (VarT k1)] [] (VarT a)            substTy = applySubstitution (Map.singleton k1 (VarT k2)) ty -           checkFreeVars :: Type -> [Name] -> Q ()+           checkFreeVars :: TH.Type -> [Name] -> Q ()            checkFreeVars t freeVars =              unless (freeVariables t == freeVars) $                fail $ "free variables of " ++ show t ++ " should be " ++ show freeVars@@ -814,11 +841,7 @@        let proxyAK  = ConT (mkName "Proxy") `AppT` SigT (VarT a) (VarT k)                         -- Proxy (a :: k)            expected = ForallT-#if __GLASGOW_HASKELL__ >= 800                         [plainTVSpecified k, kindedTVSpecified a (VarT k)]-#else-                        [kindedTVSpecified a (VarT k)]-#endif                         [] proxyAK            actual = quantifyType proxyAK        unless (expected == actual) $@@ -830,7 +853,7 @@  t61Test :: IO () t61Test =-  $(do let test :: Type -> Type -> Q ()+  $(do let test :: TH.Type -> TH.Type -> Q ()            test orig expected = do              actual <- resolveTypeSynonyms orig              unless (expected == actual) $@@ -841,22 +864,18 @@             idAppT = (ConT ''Id `AppT`)            a = mkName "a"-       test (SigT (idAppT $ ConT ''Int) (idAppT StarT))-            (SigT (ConT ''Int) StarT)-#if MIN_VERSION_template_haskell(2,10,0)-       test (ForallT [kindedTVSpecified a (idAppT StarT)]+       test (SigT (idAppT $ ConT ''Int) (idAppT starK))+            (SigT (ConT ''Int) starK)+       test (ForallT [kindedTVSpecified a (idAppT starK)]                      [idAppT (ConT ''Show `AppT` VarT a)]                      (idAppT $ VarT a))-            (ForallT [kindedTVSpecified a StarT]+            (ForallT [kindedTVSpecified a starK]                      [ConT ''Show `AppT` VarT a]                      (VarT a))-#endif-#if MIN_VERSION_template_haskell(2,11,0)        test (InfixT (idAppT $ ConT ''Int) ''Either (idAppT $ ConT ''Int))             (InfixT (ConT ''Int) ''Either (ConT ''Int))        test (ParensT (idAppT $ ConT ''Int))             (ConT ''Int)-#endif #if MIN_VERSION_template_haskell(2,19,0)        test (PromotedInfixT (idAppT $ ConT ''Int) '(:^:) (idAppT $ ConT ''Int))             (PromotedInfixT (ConT ''Int) '(:^:) (ConT ''Int))@@ -879,6 +898,7 @@            , datatypeInstTypes = [ VarT a, VarT b                                  , SigT (VarT f) fKind, SigT (VarT x) starK ]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = mkName "MkFoo"@@ -909,9 +929,7 @@                    , "Actual:   " ++ pprint actual                    ]   return ()-#endif -#if MIN_VERSION_template_haskell(2,11,0) t79TestA :: IO () t79TestA =   $(do let [a,b,c]  = map mkName ["a","b","c"]@@ -927,7 +945,6 @@                         , "Actual:   " ++ pprint actual                         ]        [| return () |])-#endif  #if MIN_VERSION_template_haskell(2,19,0) t79TestB :: IO ()@@ -947,7 +964,6 @@        [| return () |]) #endif -#if __GLASGOW_HASKELL__ >= 800 t37Test :: IO () t37Test =   $(do infoA <- reifyDatatype ''T37a@@ -964,6 +980,7 @@            , datatypeVars      = [kTvb, aTvb]            , datatypeInstTypes = [kSig, aSig]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'MkT37a@@ -982,6 +999,7 @@            , datatypeVars      = [kTvb, aTvb]            , datatypeInstTypes = [aSig]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'MkT37b@@ -1000,6 +1018,7 @@            , datatypeVars      = [kTvb, aTvb]            , datatypeInstTypes = [aSig]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'MkT37c@@ -1023,6 +1042,7 @@            , datatypeVars      = [kindedTV a starK]            , datatypeInstTypes = [SigT aVar starK]            , datatypeVariant   = Datatype+           , datatypeReturnKind = starK            , datatypeCons      =                [ ConstructorInfo                    { constructorName       = 'MkT48@@ -1044,6 +1064,8 @@            -> unless (a1 == a2) $                 fail $ "Two occurrences of the same variable have different names: "                     ++ show [a1, a2]+         _ -> fail $ "Unexpected DatatypeInfo for T48: "+                    ++ show info        [| return () |]    ) @@ -1064,7 +1086,6 @@                     ++ show (length cs)        [| return () |]    )-#endif  #if __GLASGOW_HASKELL__ >= 807 resolveTypeSynonymsVKATest :: IO ()@@ -1147,3 +1168,245 @@       wrongTy  = ForallT [plainTVSpecified a] [] (VarT a)   when (substTy == wrongTy) $     fail $ "applySubstitution captures during substitution"++#if MIN_VERSION_template_haskell(2,20,0)+t100Test :: IO ()+t100Test =+  $(do let expectedInfo =+             DatatypeInfo+               { datatypeName = ''T100+               , datatypeContext = []+               , datatypeVars = []+               , datatypeInstTypes = []+               , datatypeVariant = Datatype.TypeData+               , datatypeReturnKind = starK+               , datatypeCons =+                   [ ConstructorInfo+                       { constructorName = ''MkT100+                       , constructorContext = []+                       , constructorVars = []+                       , constructorFields = []+                       , constructorStrictness = []+                       , constructorVariant = NormalConstructor }+                   ]+               }++       t100Info <- reifyDatatype ''T100+       validateDI t100Info expectedInfo++       mkT100Info <- reifyDatatype ''MkT100+       validateDI mkT100Info expectedInfo+   )+#endif++#if MIN_VERSION_template_haskell(2,21,0)+t103Test :: IO ()+t103Test =+  $(do [dec] <- [d| data T102 @k (a :: k) |]+       info <- normalizeDec dec+       let k = mkName "k"+           a = mkName "a"+       validateDI info+         DatatypeInfo+           { datatypeName      = mkName "T102"+           , datatypeContext   = []+           , datatypeVars      = [plainTV k, kindedTV a (VarT k)]+           , datatypeInstTypes = [SigT (VarT a) (VarT k)]+           , datatypeVariant   = Datatype+           , datatypeReturnKind = starK+           , datatypeCons      = []+           }+   )+#endif++#if __GLASGOW_HASKELL__ >= 810+t107Test :: IO ()+t107Test =+  $(do info <- reifyDatatype ''T107+       let r = mkName "r"+       validateDI info+         DatatypeInfo+           { datatypeName      = mkName "T107"+           , datatypeContext   = []+           , datatypeVars      = [kindedTV r (ConT ''RuntimeRep)]+           , datatypeInstTypes = []+           , datatypeVariant   = Newtype+           , datatypeReturnKind = ConT ''TYPE `AppT` VarT r+           , datatypeCons      =+               [ ConstructorInfo+                   { constructorName       = mkName "MkT107"+                   , constructorVars       = []+                   , constructorContext    = []+                   , constructorFields     = [ConT ''Any `SigT` (ConT ''TYPE `AppT` VarT r)]+                   , constructorStrictness = [notStrictAnnot]+                   , constructorVariant    = NormalConstructor+                   }+               ]+           }+   )++t108Test :: IO ()+t108Test =+  $(do [dec] <- [d| data T108 :: forall k -> k -> Type where+                      MkT108 :: forall k (a :: k). T108 k a+                  |]+       info <- normalizeDec dec+       let k = mkName "k"+           a = mkName "a"+       validateDI info+         DatatypeInfo+           { datatypeName      = mkName "T108"+           , datatypeContext   = []+           , datatypeVars      = [plainTV k, kindedTV a (VarT k)]+           , datatypeInstTypes = [VarT k, SigT (VarT a) (VarT k)]+           , datatypeVariant   = Datatype+           , datatypeReturnKind = starK+           , datatypeCons      =+               [ ConstructorInfo+                   { constructorName       = mkName "MkT108"+                   , constructorVars       = []+                   , constructorContext    = []+                   , constructorFields     = []+                   , constructorStrictness = []+                   , constructorVariant    = NormalConstructor+                   }+               ]+           }+   )+#endif++#if __GLASGOW_HASKELL__ >= 804+t110Test :: IO ()+t110Test =+  $(do [dec] <- [d| data T110 :: forall k. k -> Type where+                      MkT110 :: forall k (a :: k). T110 a+                  |]+       info <- normalizeDec dec+       let k = mkName "k"+           a = mkName "a"+       validateDI info+         DatatypeInfo+           { datatypeName      = mkName "T110"+           , datatypeContext   = []+           , datatypeVars      = [plainTV k, kindedTV a (VarT k)]+           , datatypeInstTypes = [SigT (VarT a) (VarT k)]+           , datatypeVariant   = Datatype+           , datatypeReturnKind = starK+           , datatypeCons      =+               [ ConstructorInfo+                   { constructorName       = mkName "MkT110"+                   , constructorVars       = []+                   , constructorContext    = []+                   , constructorFields     = []+                   , constructorStrictness = []+                   , constructorVariant    = NormalConstructor+                   }+               ]+           }+   )+#endif++#if MIN_VERSION_template_haskell(2,16,0)+unboxedTupleTest :: IO ()+unboxedTupleTest =+  $(do k0 <- newName "k0"+       k1 <- newName "k1"+       a <- newName "a"+       b  <- newName "b"+       tupleInfo <- reifyDatatype (unboxedTupleTypeName 2)+       validateDI tupleInfo+         DatatypeInfo+           { datatypeContext = []+           , datatypeName = unboxedTupleTypeName 2+           , datatypeVars = [kindedTV k0 starK+                            ,kindedTV a (AppT (ConT ''TYPE) (VarT k0 ))+                            ,kindedTV k1 starK+                            ,kindedTV b (AppT (ConT ''TYPE) (VarT k1))]+           , datatypeInstTypes = [SigT (VarT a) (AppT (ConT ''TYPE) (VarT k0))+                                 ,SigT (VarT b) (AppT (ConT ''TYPE) (VarT k1))]+           , datatypeVariant = Datatype+           , datatypeReturnKind =+               AppT+                 (ConT ''TYPE)+                 (AppT+                    (PromotedT 'TupleRep)+                    (AppT+                      (AppT PromotedConsT (VarT k0))+                        (AppT+                          (AppT PromotedConsT (VarT k1))+                          (SigT PromotedNilT (AppT ListT (ConT ''RuntimeRep))))))+           , datatypeCons =+             [ ConstructorInfo+               { constructorName = unboxedTupleDataName 2+               , constructorVars = []+               , constructorContext = []+               , constructorFields = [VarT a, VarT b]+               , constructorStrictness = [notStrictAnnot, notStrictAnnot]+               , constructorVariant = NormalConstructor}]+          }+  )+#endif++#if MIN_VERSION_template_haskell(2,18,0)+unliftedGADTDecTest :: IO ()+unliftedGADTDecTest =+  $(do a <- newName "a"+       s <- newName "s"+       [dec] <- [d| data UnliftedGADT a :: UnliftedType where+                      UnliftedGADT :: Show s => s -> a -> UnliftedGADT a+                |]+       info <- normalizeDec dec+       validateDI info+         DatatypeInfo+           { datatypeContext = []+           , datatypeName = mkName "UnliftedGADT"+           , datatypeVars = [plainTV a]+           , datatypeInstTypes = [VarT a]+           , datatypeVariant = Datatype+           , datatypeReturnKind = ConT ''TYPE `AppT` (PromotedT 'BoxedRep `AppT` PromotedT 'Unlifted)+           , datatypeCons =+               [ConstructorInfo+                  {constructorName = mkName "UnliftedGADT"+                  , constructorVars = [plainTV s]+                  , constructorContext = [AppT (ConT ''Show) (VarT s)]+                  , constructorFields = [VarT s,VarT a]+                  , constructorStrictness = [notStrictAnnot, notStrictAnnot]+                  , constructorVariant = NormalConstructor}+               ]+           }+   )+#endif+++primTyConTest :: IO ()+primTyConTest =+  $(do l <- newName "l"+       a <- newName "a"+       info <- reifyDatatype ''Array#+       validateDI info+         DatatypeInfo+           { datatypeContext = []+           , datatypeName = mkName "Array#"+#if MIN_VERSION_template_haskell(2,19,0)+           , datatypeVars = [kindedTV l (ConT ''Levity)+                            , kindedTV a (ConT ''TYPE `AppT` (PromotedT 'BoxedRep `AppT` VarT l))+                            ]+           , datatypeInstTypes = [SigT (VarT a) (ConT ''TYPE `AppT` (PromotedT 'BoxedRep `AppT` VarT l))]+           , datatypeReturnKind = ConT ''TYPE `AppT` (PromotedT 'BoxedRep `AppT` PromotedT 'Unlifted)+#elif MIN_VERSION_template_haskell(2,18,0)+           , datatypeVars = [ kindedTV a StarT]+           , datatypeInstTypes = [SigT (VarT a) StarT]+           , datatypeReturnKind = ConT ''TYPE `AppT` (PromotedT 'BoxedRep `AppT` PromotedT 'Unlifted)+#elif MIN_VERSION_template_haskell(2,16,0)+           , datatypeVars = [kindedTV a starK]+           , datatypeInstTypes = [SigT (VarT a) starK]+           , datatypeReturnKind = ConT ''TYPE `AppT` PromotedT 'UnliftedRep+#else+           , datatypeVars = [kindedTV a starK]+           , datatypeInstTypes = [SigT (VarT a) starK]+           , datatypeReturnKind = starK+#endif+           , datatypeVariant = Datatype+           , datatypeCons = []+           }+   )
test/Types.hs view
@@ -1,17 +1,22 @@-{-# Language CPP, FlexibleContexts, TypeFamilies, KindSignatures, TemplateHaskell, GADTs, ScopedTypeVariables, TypeOperators #-}+{-# Language CPP, FlexibleContexts, TypeFamilies, KindSignatures, TemplateHaskell, GADTs, ScopedTypeVariables, TypeOperators, ConstraintKinds, DataKinds, PolyKinds #-} -#if __GLASGOW_HASKELL__ >= 704-{-# LANGUAGE ConstraintKinds #-}+#if __GLASGOW_HASKELL__ < 806+{-# Language TypeInType #-} #endif -#if MIN_VERSION_template_haskell(2,8,0)-{-# Language PolyKinds #-}+#if __GLASGOW_HASKELL__ >= 810+{-# Language StandaloneKindSignatures #-}+{-# Language TypeApplications #-}+{-# Language UnliftedNewtypes #-} #endif -#if __GLASGOW_HASKELL__ >= 800-{-# Language TypeInType #-}+#if MIN_VERSION_template_haskell(2,20,0)+{-# Language TypeData #-} #endif +-- We should aim to enable -Wincomplete-uni-patterns long-term. See #121.+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+ {-| Module      : Types Description : Test cases for the th-abstraction package@@ -25,17 +30,17 @@ -} module Types where -#if __GLASGOW_HASKELL__ >= 704+import Data.Kind+ import GHC.Exts (Constraint)-#endif  import Language.Haskell.TH hiding (Type) import Language.Haskell.TH.Datatype import Language.Haskell.TH.Datatype.TyVarBndr import Language.Haskell.TH.Lib (starK) -#if __GLASGOW_HASKELL__ >= 800-import Data.Kind+#if __GLASGOW_HASKELL__ >= 810+import GHC.Exts (Any, TYPE) #endif  type Gadt1Int = Gadt1 Int@@ -78,24 +83,15 @@  type Id (a :: *) = a -#if MIN_VERSION_template_haskell(2,7,0) data family DF (a :: *) data instance DF (Maybe a) = DFMaybe Int [a] -# if MIN_VERSION_template_haskell(2,8,0) data family DF1 (a :: k)-# else-data family DF1 (a :: *)-# endif data instance DF1 (b :: *) = DF1 b  data family Quoted (a :: *) -# if MIN_VERSION_template_haskell(2,8,0) data family Poly (a :: k)-# else-data family Poly (a :: *)-# endif data instance Poly a = MkPoly  data family GadtFam (a :: *) (b :: *)@@ -119,9 +115,7 @@  data family T95 :: * -> * data instance T95 [a] = MkT95 a-#endif -#if __GLASGOW_HASKELL__ >= 704 type Konst (a :: Constraint) (b :: Constraint) = a type PredSyn1 a b = Konst (Show a) (Read b) type PredSyn2 a b = Konst (PredSyn1 a b) (Show a)@@ -131,15 +125,19 @@     PredSyn1 Int Int => MkPredSynT1 Int   | PredSyn2 Int Int => MkPredSynT2 Int   | PredSyn3 Int     => MkPredSynT3 Int-#endif -#if __GLASGOW_HASKELL__ >= 800 data T37a (k :: Type) :: k -> Type where   MkT37a :: T37a Bool a +#if __GLASGOW_HASKELL__ >= 810+type T37b :: k -> Type+#endif data T37b (a :: k) where   MkT37b :: forall (a :: Bool). T37b a +#if __GLASGOW_HASKELL__ >= 810+type T37c :: k -> Type+#endif data T37c (a :: k) where   MkT37c :: T37c Bool @@ -150,8 +148,17 @@  data T75 (k :: Type) where   MkT75 :: forall k (a :: k). Prox a -> T75 k++#if MIN_VERSION_template_haskell(2,20,0)+type data T100 = MkT100 #endif +#if __GLASGOW_HASKELL__ >= 810+type T107 :: TYPE r+newtype T107 where+  MkT107 :: forall r. Any @(TYPE r) -> T107 @r+#endif+ -- We must define these here due to Template Haskell staging restrictions justCI :: ConstructorInfo justCI =@@ -179,7 +186,6 @@     names@[v1,v2] = map mkName ["v1","v2"]     [v1K,v2K]     = map (\n -> kindedTV n starK) names -#if MIN_VERSION_template_haskell(2,7,0) gadtRecFamCI :: ConstructorInfo gadtRecFamCI =   ConstructorInfo@@ -193,4 +199,3 @@     , constructorVariant    = RecordConstructor ['famRec1, 'famRec2] }   where     [cTy,dTy] = map (VarT . mkName) ["c", "d"]-#endif
th-abstraction.cabal view
@@ -1,5 +1,5 @@ name:                th-abstraction-version:             0.4.5.0+version:             0.7.2.0 synopsis:            Nicer interface for reified information about data types description:         This package normalizes variations in the interface for                      inspecting datatype information via Template Haskell@@ -17,7 +17,7 @@ build-type:          Simple extra-source-files:  ChangeLog.md README.md cabal-version:       >=1.10-tested-with:         GHC==9.2.2, GHC==9.0.2, GHC==8.10.7, GHC==8.8.4, GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, GHC==7.2.2, GHC==7.0.4+tested-with:         GHC==9.14.1, GHC==9.12.2, GHC==9.10.3, GHC==9.8.4, GHC==9.6.7, GHC==9.4.8, GHC==9.2.8, GHC==9.0.2, GHC==8.10.7, GHC==8.8.4, GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2  source-repository head   type: git@@ -27,10 +27,9 @@   exposed-modules:     Language.Haskell.TH.Datatype                        Language.Haskell.TH.Datatype.TyVarBndr   other-modules:       Language.Haskell.TH.Datatype.Internal-  build-depends:       base             >=4.3   && <5,-                       ghc-prim,-                       template-haskell >=2.5   && <2.20,-                       containers       >=0.4   && <0.7+  build-depends:       base             >=4.9   && <5,+                       template-haskell >=2.11  && <2.25,+                       containers       >=0.4   && <0.9   hs-source-dirs:      src   default-language:    Haskell2010 @@ -47,3 +46,6 @@   build-depends:       th-abstraction, base, containers, template-haskell   hs-source-dirs:      test   default-language:    Haskell2010++  if impl(ghc >= 8.6)+    ghc-options:       -Wno-star-is-type