    {-# 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
      { DatatypeInfo -> [Type]
    datatypeContext   :: Cxt               -- ^ Data type context (deprecated)
      , DatatypeInfo -> Name
    datatypeName      :: Name              -- ^ Type constructor
      , DatatypeInfo -> [TyVarBndrUnit]
    datatypeVars      :: [TyVarBndrUnit]   -- ^ Type parameters
      , DatatypeInfo -> [Type]
    datatypeInstTypes :: [Type]            -- ^ Argument types
      , DatatypeInfo -> DatatypeVariant
    datatypeVariant   :: DatatypeVariant   -- ^ Extra information
      , DatatypeInfo -> Type
    datatypeReturnKind:: Kind              -- ^ Return 'Kind' of the type.
                                               --
                                               -- If normalization is unable to determine the return kind,
                                               -- then this is conservatively set to @StarT@.
      , DatatypeInfo -> [ConstructorInfo]
    datatypeCons      :: [ConstructorInfo] -- ^ Normalize constructor information
      }
      deriving (Int -> DatatypeInfo -> ShowS
    [DatatypeInfo] -> ShowS
    DatatypeInfo -> String
    (Int -> DatatypeInfo -> ShowS)
    -> (DatatypeInfo -> String)
    -> ([DatatypeInfo] -> ShowS)
    -> Show DatatypeInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> DatatypeInfo -> ShowS
    showsPrec :: Int -> DatatypeInfo -> ShowS
    $cshow :: DatatypeInfo -> String
    show :: DatatypeInfo -> String
    $cshowList :: [DatatypeInfo] -> ShowS
    showList :: [DatatypeInfo] -> ShowS
    Show, DatatypeInfo -> DatatypeInfo -> Bool
    (DatatypeInfo -> DatatypeInfo -> Bool)
    -> (DatatypeInfo -> DatatypeInfo -> Bool) -> Eq DatatypeInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DatatypeInfo -> DatatypeInfo -> Bool
    == :: DatatypeInfo -> DatatypeInfo -> Bool
    $c/= :: DatatypeInfo -> DatatypeInfo -> Bool
    /= :: DatatypeInfo -> DatatypeInfo -> Bool
    Eq, Typeable DatatypeInfo
    Typeable DatatypeInfo =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> DatatypeInfo -> c DatatypeInfo)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c DatatypeInfo)
    -> (DatatypeInfo -> Constr)
    -> (DatatypeInfo -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c DatatypeInfo))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c DatatypeInfo))
    -> ((forall b. Data b => b -> b) -> DatatypeInfo -> DatatypeInfo)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r)
    -> (forall u. (forall d. Data d => d -> u) -> DatatypeInfo -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> DatatypeInfo -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo)
    -> Data DatatypeInfo
    DatatypeInfo -> Constr
    DatatypeInfo -> DataType
    (forall b. Data b => b -> b) -> DatatypeInfo -> DatatypeInfo
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> DatatypeInfo -> u
    forall u. (forall d. Data d => d -> u) -> DatatypeInfo -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DatatypeInfo
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DatatypeInfo -> c DatatypeInfo
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DatatypeInfo)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DatatypeInfo)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DatatypeInfo -> c DatatypeInfo
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DatatypeInfo -> c DatatypeInfo
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DatatypeInfo
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DatatypeInfo
    $ctoConstr :: DatatypeInfo -> Constr
    toConstr :: DatatypeInfo -> Constr
    $cdataTypeOf :: DatatypeInfo -> DataType
    dataTypeOf :: DatatypeInfo -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DatatypeInfo)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DatatypeInfo)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DatatypeInfo)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DatatypeInfo)
    $cgmapT :: (forall b. Data b => b -> b) -> DatatypeInfo -> DatatypeInfo
    gmapT :: (forall b. Data b => b -> b) -> DatatypeInfo -> DatatypeInfo
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeInfo -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> DatatypeInfo -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> DatatypeInfo -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DatatypeInfo -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DatatypeInfo -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DatatypeInfo -> m DatatypeInfo
    Data, (forall x. DatatypeInfo -> Rep DatatypeInfo x)
    -> (forall x. Rep DatatypeInfo x -> DatatypeInfo)
    -> Generic DatatypeInfo
    forall x. Rep DatatypeInfo x -> DatatypeInfo
    forall x. DatatypeInfo -> Rep DatatypeInfo x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. DatatypeInfo -> Rep DatatypeInfo x
    from :: forall x. DatatypeInfo -> Rep DatatypeInfo x
    $cto :: forall x. Rep DatatypeInfo x -> DatatypeInfo
    to :: forall x. Rep DatatypeInfo x -> DatatypeInfo
    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 (Int -> DatatypeVariant -> ShowS
    [DatatypeVariant] -> ShowS
    DatatypeVariant -> String
    (Int -> DatatypeVariant -> ShowS)
    -> (DatatypeVariant -> String)
    -> ([DatatypeVariant] -> ShowS)
    -> Show DatatypeVariant
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> DatatypeVariant -> ShowS
    showsPrec :: Int -> DatatypeVariant -> ShowS
    $cshow :: DatatypeVariant -> String
    show :: DatatypeVariant -> String
    $cshowList :: [DatatypeVariant] -> ShowS
    showList :: [DatatypeVariant] -> ShowS
    Show, ReadPrec [DatatypeVariant]
    ReadPrec DatatypeVariant
    Int -> ReadS DatatypeVariant
    ReadS [DatatypeVariant]
    (Int -> ReadS DatatypeVariant)
    -> ReadS [DatatypeVariant]
    -> ReadPrec DatatypeVariant
    -> ReadPrec [DatatypeVariant]
    -> Read DatatypeVariant
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS DatatypeVariant
    readsPrec :: Int -> ReadS DatatypeVariant
    $creadList :: ReadS [DatatypeVariant]
    readList :: ReadS [DatatypeVariant]
    $creadPrec :: ReadPrec DatatypeVariant
    readPrec :: ReadPrec DatatypeVariant
    $creadListPrec :: ReadPrec [DatatypeVariant]
    readListPrec :: ReadPrec [DatatypeVariant]
    Read, DatatypeVariant -> DatatypeVariant -> Bool
    (DatatypeVariant -> DatatypeVariant -> Bool)
    -> (DatatypeVariant -> DatatypeVariant -> Bool)
    -> Eq DatatypeVariant
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DatatypeVariant -> DatatypeVariant -> Bool
    == :: DatatypeVariant -> DatatypeVariant -> Bool
    $c/= :: DatatypeVariant -> DatatypeVariant -> Bool
    /= :: DatatypeVariant -> DatatypeVariant -> Bool
    Eq, Eq DatatypeVariant
    Eq DatatypeVariant =>
    (DatatypeVariant -> DatatypeVariant -> Ordering)
    -> (DatatypeVariant -> DatatypeVariant -> Bool)
    -> (DatatypeVariant -> DatatypeVariant -> Bool)
    -> (DatatypeVariant -> DatatypeVariant -> Bool)
    -> (DatatypeVariant -> DatatypeVariant -> Bool)
    -> (DatatypeVariant -> DatatypeVariant -> DatatypeVariant)
    -> (DatatypeVariant -> DatatypeVariant -> DatatypeVariant)
    -> Ord DatatypeVariant
    DatatypeVariant -> DatatypeVariant -> Bool
    DatatypeVariant -> DatatypeVariant -> Ordering
    DatatypeVariant -> DatatypeVariant -> DatatypeVariant
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: DatatypeVariant -> DatatypeVariant -> Ordering
    compare :: DatatypeVariant -> DatatypeVariant -> Ordering
    $c< :: DatatypeVariant -> DatatypeVariant -> Bool
    < :: DatatypeVariant -> DatatypeVariant -> Bool
    $c<= :: DatatypeVariant -> DatatypeVariant -> Bool
    <= :: DatatypeVariant -> DatatypeVariant -> Bool
    $c> :: DatatypeVariant -> DatatypeVariant -> Bool
    > :: DatatypeVariant -> DatatypeVariant -> Bool
    $c>= :: DatatypeVariant -> DatatypeVariant -> Bool
    >= :: DatatypeVariant -> DatatypeVariant -> Bool
    $cmax :: DatatypeVariant -> DatatypeVariant -> DatatypeVariant
    max :: DatatypeVariant -> DatatypeVariant -> DatatypeVariant
    $cmin :: DatatypeVariant -> DatatypeVariant -> DatatypeVariant
    min :: DatatypeVariant -> DatatypeVariant -> DatatypeVariant
    Ord, Typeable DatatypeVariant
    Typeable DatatypeVariant =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> DatatypeVariant -> c DatatypeVariant)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c DatatypeVariant)
    -> (DatatypeVariant -> Constr)
    -> (DatatypeVariant -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c DatatypeVariant))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c DatatypeVariant))
    -> ((forall b. Data b => b -> b)
        -> DatatypeVariant -> DatatypeVariant)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> DatatypeVariant -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> DatatypeVariant -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> DatatypeVariant -> m DatatypeVariant)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> DatatypeVariant -> m DatatypeVariant)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> DatatypeVariant -> m DatatypeVariant)
    -> Data DatatypeVariant
    DatatypeVariant -> Constr
    DatatypeVariant -> DataType
    (forall b. Data b => b -> b) -> DatatypeVariant -> DatatypeVariant
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> DatatypeVariant -> u
    forall u. (forall d. Data d => d -> u) -> DatatypeVariant -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> DatatypeVariant -> m DatatypeVariant
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DatatypeVariant -> m DatatypeVariant
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DatatypeVariant
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DatatypeVariant -> c DatatypeVariant
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DatatypeVariant)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DatatypeVariant)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DatatypeVariant -> c DatatypeVariant
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DatatypeVariant -> c DatatypeVariant
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DatatypeVariant
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DatatypeVariant
    $ctoConstr :: DatatypeVariant -> Constr
    toConstr :: DatatypeVariant -> Constr
    $cdataTypeOf :: DatatypeVariant -> DataType
    dataTypeOf :: DatatypeVariant -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DatatypeVariant)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DatatypeVariant)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DatatypeVariant)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DatatypeVariant)
    $cgmapT :: (forall b. Data b => b -> b) -> DatatypeVariant -> DatatypeVariant
    gmapT :: (forall b. Data b => b -> b) -> DatatypeVariant -> DatatypeVariant
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DatatypeVariant -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> DatatypeVariant -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> DatatypeVariant -> [u]
    $cgmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> DatatypeVariant -> u
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> DatatypeVariant -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> DatatypeVariant -> m DatatypeVariant
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> DatatypeVariant -> m DatatypeVariant
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DatatypeVariant -> m DatatypeVariant
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DatatypeVariant -> m DatatypeVariant
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DatatypeVariant -> m DatatypeVariant
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DatatypeVariant -> m DatatypeVariant
    Data, (forall x. DatatypeVariant -> Rep DatatypeVariant x)
    -> (forall x. Rep DatatypeVariant x -> DatatypeVariant)
    -> Generic DatatypeVariant
    forall x. Rep DatatypeVariant x -> DatatypeVariant
    forall x. DatatypeVariant -> Rep DatatypeVariant x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. DatatypeVariant -> Rep DatatypeVariant x
    from :: forall x. DatatypeVariant -> Rep DatatypeVariant x
    $cto :: forall x. Rep DatatypeVariant x -> DatatypeVariant
    to :: forall x. Rep DatatypeVariant x -> DatatypeVariant
    Generic)

    -- | Normalized information about constructors associated with newtypes and
    -- data types.
    data ConstructorInfo = ConstructorInfo
      { ConstructorInfo -> Name
    constructorName       :: Name               -- ^ Constructor name
      , ConstructorInfo -> [TyVarBndrUnit]
    constructorVars       :: [TyVarBndrUnit]    -- ^ Constructor type parameters
      , ConstructorInfo -> [Type]
    constructorContext    :: Cxt                -- ^ Constructor constraints
      , ConstructorInfo -> [Type]
    constructorFields     :: [Type]             -- ^ Constructor fields
      , ConstructorInfo -> [FieldStrictness]
    constructorStrictness :: [FieldStrictness]  -- ^ Constructor fields' strictness
                                                    --   (Invariant: has the same length
                                                    --   as constructorFields)
      , ConstructorInfo -> ConstructorVariant
    constructorVariant    :: ConstructorVariant -- ^ Extra information
      }
      deriving (Int -> ConstructorInfo -> ShowS
    [ConstructorInfo] -> ShowS
    ConstructorInfo -> String
    (Int -> ConstructorInfo -> ShowS)
    -> (ConstructorInfo -> String)
    -> ([ConstructorInfo] -> ShowS)
    -> Show ConstructorInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ConstructorInfo -> ShowS
    showsPrec :: Int -> ConstructorInfo -> ShowS
    $cshow :: ConstructorInfo -> String
    show :: ConstructorInfo -> String
    $cshowList :: [ConstructorInfo] -> ShowS
    showList :: [ConstructorInfo] -> ShowS
    Show, ConstructorInfo -> ConstructorInfo -> Bool
    (ConstructorInfo -> ConstructorInfo -> Bool)
    -> (ConstructorInfo -> ConstructorInfo -> Bool)
    -> Eq ConstructorInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ConstructorInfo -> ConstructorInfo -> Bool
    == :: ConstructorInfo -> ConstructorInfo -> Bool
    $c/= :: ConstructorInfo -> ConstructorInfo -> Bool
    /= :: ConstructorInfo -> ConstructorInfo -> Bool
    Eq, Typeable ConstructorInfo
    Typeable ConstructorInfo =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> ConstructorInfo -> c ConstructorInfo)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c ConstructorInfo)
    -> (ConstructorInfo -> Constr)
    -> (ConstructorInfo -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c ConstructorInfo))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c ConstructorInfo))
    -> ((forall b. Data b => b -> b)
        -> ConstructorInfo -> ConstructorInfo)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> ConstructorInfo -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> ConstructorInfo -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> ConstructorInfo -> m ConstructorInfo)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> ConstructorInfo -> m ConstructorInfo)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> ConstructorInfo -> m ConstructorInfo)
    -> Data ConstructorInfo
    ConstructorInfo -> Constr
    ConstructorInfo -> DataType
    (forall b. Data b => b -> b) -> ConstructorInfo -> ConstructorInfo
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> ConstructorInfo -> u
    forall u. (forall d. Data d => d -> u) -> ConstructorInfo -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ConstructorInfo -> m ConstructorInfo
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorInfo -> m ConstructorInfo
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ConstructorInfo
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ConstructorInfo -> c ConstructorInfo
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ConstructorInfo)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ConstructorInfo)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ConstructorInfo -> c ConstructorInfo
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ConstructorInfo -> c ConstructorInfo
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ConstructorInfo
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ConstructorInfo
    $ctoConstr :: ConstructorInfo -> Constr
    toConstr :: ConstructorInfo -> Constr
    $cdataTypeOf :: ConstructorInfo -> DataType
    dataTypeOf :: ConstructorInfo -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ConstructorInfo)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ConstructorInfo)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ConstructorInfo)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ConstructorInfo)
    $cgmapT :: (forall b. Data b => b -> b) -> ConstructorInfo -> ConstructorInfo
    gmapT :: (forall b. Data b => b -> b) -> ConstructorInfo -> ConstructorInfo
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorInfo -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> ConstructorInfo -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> ConstructorInfo -> [u]
    $cgmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> ConstructorInfo -> u
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> ConstructorInfo -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ConstructorInfo -> m ConstructorInfo
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ConstructorInfo -> m ConstructorInfo
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorInfo -> m ConstructorInfo
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorInfo -> m ConstructorInfo
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorInfo -> m ConstructorInfo
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorInfo -> m ConstructorInfo
    Data, (forall x. ConstructorInfo -> Rep ConstructorInfo x)
    -> (forall x. Rep ConstructorInfo x -> ConstructorInfo)
    -> Generic ConstructorInfo
    forall x. Rep ConstructorInfo x -> ConstructorInfo
    forall x. ConstructorInfo -> Rep ConstructorInfo x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. ConstructorInfo -> Rep ConstructorInfo x
    from :: forall x. ConstructorInfo -> Rep ConstructorInfo x
    $cto :: forall x. Rep ConstructorInfo x -> ConstructorInfo
    to :: forall x. Rep ConstructorInfo x -> ConstructorInfo
    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 (Int -> ConstructorVariant -> ShowS
    [ConstructorVariant] -> ShowS
    ConstructorVariant -> String
    (Int -> ConstructorVariant -> ShowS)
    -> (ConstructorVariant -> String)
    -> ([ConstructorVariant] -> ShowS)
    -> Show ConstructorVariant
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ConstructorVariant -> ShowS
    showsPrec :: Int -> ConstructorVariant -> ShowS
    $cshow :: ConstructorVariant -> String
    show :: ConstructorVariant -> String
    $cshowList :: [ConstructorVariant] -> ShowS
    showList :: [ConstructorVariant] -> ShowS
    Show, ConstructorVariant -> ConstructorVariant -> Bool
    (ConstructorVariant -> ConstructorVariant -> Bool)
    -> (ConstructorVariant -> ConstructorVariant -> Bool)
    -> Eq ConstructorVariant
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ConstructorVariant -> ConstructorVariant -> Bool
    == :: ConstructorVariant -> ConstructorVariant -> Bool
    $c/= :: ConstructorVariant -> ConstructorVariant -> Bool
    /= :: ConstructorVariant -> ConstructorVariant -> Bool
    Eq, Eq ConstructorVariant
    Eq ConstructorVariant =>
    (ConstructorVariant -> ConstructorVariant -> Ordering)
    -> (ConstructorVariant -> ConstructorVariant -> Bool)
    -> (ConstructorVariant -> ConstructorVariant -> Bool)
    -> (ConstructorVariant -> ConstructorVariant -> Bool)
    -> (ConstructorVariant -> ConstructorVariant -> Bool)
    -> (ConstructorVariant -> ConstructorVariant -> ConstructorVariant)
    -> (ConstructorVariant -> ConstructorVariant -> ConstructorVariant)
    -> Ord ConstructorVariant
    ConstructorVariant -> ConstructorVariant -> Bool
    ConstructorVariant -> ConstructorVariant -> Ordering
    ConstructorVariant -> ConstructorVariant -> ConstructorVariant
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ConstructorVariant -> ConstructorVariant -> Ordering
    compare :: ConstructorVariant -> ConstructorVariant -> Ordering
    $c< :: ConstructorVariant -> ConstructorVariant -> Bool
    < :: ConstructorVariant -> ConstructorVariant -> Bool
    $c<= :: ConstructorVariant -> ConstructorVariant -> Bool
    <= :: ConstructorVariant -> ConstructorVariant -> Bool
    $c> :: ConstructorVariant -> ConstructorVariant -> Bool
    > :: ConstructorVariant -> ConstructorVariant -> Bool
    $c>= :: ConstructorVariant -> ConstructorVariant -> Bool
    >= :: ConstructorVariant -> ConstructorVariant -> Bool
    $cmax :: ConstructorVariant -> ConstructorVariant -> ConstructorVariant
    max :: ConstructorVariant -> ConstructorVariant -> ConstructorVariant
    $cmin :: ConstructorVariant -> ConstructorVariant -> ConstructorVariant
    min :: ConstructorVariant -> ConstructorVariant -> ConstructorVariant
    Ord, Typeable ConstructorVariant
    Typeable ConstructorVariant =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g)
     -> ConstructorVariant
     -> c ConstructorVariant)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c ConstructorVariant)
    -> (ConstructorVariant -> Constr)
    -> (ConstructorVariant -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c ConstructorVariant))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c ConstructorVariant))
    -> ((forall b. Data b => b -> b)
        -> ConstructorVariant -> ConstructorVariant)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> ConstructorVariant -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> ConstructorVariant -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> ConstructorVariant -> m ConstructorVariant)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> ConstructorVariant -> m ConstructorVariant)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> ConstructorVariant -> m ConstructorVariant)
    -> Data ConstructorVariant
    ConstructorVariant -> Constr
    ConstructorVariant -> DataType
    (forall b. Data b => b -> b)
    -> ConstructorVariant -> ConstructorVariant
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> ConstructorVariant -> u
    forall u. (forall d. Data d => d -> u) -> ConstructorVariant -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ConstructorVariant -> m ConstructorVariant
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorVariant -> m ConstructorVariant
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ConstructorVariant
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> ConstructorVariant
    -> c ConstructorVariant
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ConstructorVariant)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ConstructorVariant)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> ConstructorVariant
    -> c ConstructorVariant
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> ConstructorVariant
    -> c ConstructorVariant
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ConstructorVariant
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ConstructorVariant
    $ctoConstr :: ConstructorVariant -> Constr
    toConstr :: ConstructorVariant -> Constr
    $cdataTypeOf :: ConstructorVariant -> DataType
    dataTypeOf :: ConstructorVariant -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ConstructorVariant)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ConstructorVariant)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ConstructorVariant)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ConstructorVariant)
    $cgmapT :: (forall b. Data b => b -> b)
    -> ConstructorVariant -> ConstructorVariant
    gmapT :: (forall b. Data b => b -> b)
    -> ConstructorVariant -> ConstructorVariant
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ConstructorVariant -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> ConstructorVariant -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> ConstructorVariant -> [u]
    $cgmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> ConstructorVariant -> u
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> ConstructorVariant -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ConstructorVariant -> m ConstructorVariant
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ConstructorVariant -> m ConstructorVariant
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorVariant -> m ConstructorVariant
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorVariant -> m ConstructorVariant
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorVariant -> m ConstructorVariant
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ConstructorVariant -> m ConstructorVariant
    Data, (forall x. ConstructorVariant -> Rep ConstructorVariant x)
    -> (forall x. Rep ConstructorVariant x -> ConstructorVariant)
    -> Generic ConstructorVariant
    forall x. Rep ConstructorVariant x -> ConstructorVariant
    forall x. ConstructorVariant -> Rep ConstructorVariant x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. ConstructorVariant -> Rep ConstructorVariant x
    from :: forall x. ConstructorVariant -> Rep ConstructorVariant x
    $cto :: forall x. Rep ConstructorVariant x -> ConstructorVariant
    to :: forall x. Rep ConstructorVariant x -> ConstructorVariant
    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
      { FieldStrictness -> Unpackedness
    fieldUnpackedness :: Unpackedness
      , FieldStrictness -> Strictness
    fieldStrictness   :: Strictness
      }
      deriving (Int -> FieldStrictness -> ShowS
    [FieldStrictness] -> ShowS
    FieldStrictness -> String
    (Int -> FieldStrictness -> ShowS)
    -> (FieldStrictness -> String)
    -> ([FieldStrictness] -> ShowS)
    -> Show FieldStrictness
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> FieldStrictness -> ShowS
    showsPrec :: Int -> FieldStrictness -> ShowS
    $cshow :: FieldStrictness -> String
    show :: FieldStrictness -> String
    $cshowList :: [FieldStrictness] -> ShowS
    showList :: [FieldStrictness] -> ShowS
    Show, FieldStrictness -> FieldStrictness -> Bool
    (FieldStrictness -> FieldStrictness -> Bool)
    -> (FieldStrictness -> FieldStrictness -> Bool)
    -> Eq FieldStrictness
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: FieldStrictness -> FieldStrictness -> Bool
    == :: FieldStrictness -> FieldStrictness -> Bool
    $c/= :: FieldStrictness -> FieldStrictness -> Bool
    /= :: FieldStrictness -> FieldStrictness -> Bool
    Eq, Eq FieldStrictness
    Eq FieldStrictness =>
    (FieldStrictness -> FieldStrictness -> Ordering)
    -> (FieldStrictness -> FieldStrictness -> Bool)
    -> (FieldStrictness -> FieldStrictness -> Bool)
    -> (FieldStrictness -> FieldStrictness -> Bool)
    -> (FieldStrictness -> FieldStrictness -> Bool)
    -> (FieldStrictness -> FieldStrictness -> FieldStrictness)
    -> (FieldStrictness -> FieldStrictness -> FieldStrictness)
    -> Ord FieldStrictness
    FieldStrictness -> FieldStrictness -> Bool
    FieldStrictness -> FieldStrictness -> Ordering
    FieldStrictness -> FieldStrictness -> FieldStrictness
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: FieldStrictness -> FieldStrictness -> Ordering
    compare :: FieldStrictness -> FieldStrictness -> Ordering
    $c< :: FieldStrictness -> FieldStrictness -> Bool
    < :: FieldStrictness -> FieldStrictness -> Bool
    $c<= :: FieldStrictness -> FieldStrictness -> Bool
    <= :: FieldStrictness -> FieldStrictness -> Bool
    $c> :: FieldStrictness -> FieldStrictness -> Bool
    > :: FieldStrictness -> FieldStrictness -> Bool
    $c>= :: FieldStrictness -> FieldStrictness -> Bool
    >= :: FieldStrictness -> FieldStrictness -> Bool
    $cmax :: FieldStrictness -> FieldStrictness -> FieldStrictness
    max :: FieldStrictness -> FieldStrictness -> FieldStrictness
    $cmin :: FieldStrictness -> FieldStrictness -> FieldStrictness
    min :: FieldStrictness -> FieldStrictness -> FieldStrictness
    Ord, Typeable FieldStrictness
    Typeable FieldStrictness =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> FieldStrictness -> c FieldStrictness)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c FieldStrictness)
    -> (FieldStrictness -> Constr)
    -> (FieldStrictness -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c FieldStrictness))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c FieldStrictness))
    -> ((forall b. Data b => b -> b)
        -> FieldStrictness -> FieldStrictness)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> FieldStrictness -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> FieldStrictness -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> FieldStrictness -> m FieldStrictness)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> FieldStrictness -> m FieldStrictness)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> FieldStrictness -> m FieldStrictness)
    -> Data FieldStrictness
    FieldStrictness -> Constr
    FieldStrictness -> DataType
    (forall b. Data b => b -> b) -> FieldStrictness -> FieldStrictness
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> FieldStrictness -> u
    forall u. (forall d. Data d => d -> u) -> FieldStrictness -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> FieldStrictness -> m FieldStrictness
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> FieldStrictness -> m FieldStrictness
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c FieldStrictness
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> FieldStrictness -> c FieldStrictness
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c FieldStrictness)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c FieldStrictness)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> FieldStrictness -> c FieldStrictness
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> FieldStrictness -> c FieldStrictness
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c FieldStrictness
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c FieldStrictness
    $ctoConstr :: FieldStrictness -> Constr
    toConstr :: FieldStrictness -> Constr
    $cdataTypeOf :: FieldStrictness -> DataType
    dataTypeOf :: FieldStrictness -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c FieldStrictness)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c FieldStrictness)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c FieldStrictness)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c FieldStrictness)
    $cgmapT :: (forall b. Data b => b -> b) -> FieldStrictness -> FieldStrictness
    gmapT :: (forall b. Data b => b -> b) -> FieldStrictness -> FieldStrictness
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> FieldStrictness -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> FieldStrictness -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> FieldStrictness -> [u]
    $cgmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> FieldStrictness -> u
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> FieldStrictness -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> FieldStrictness -> m FieldStrictness
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> FieldStrictness -> m FieldStrictness
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> FieldStrictness -> m FieldStrictness
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> FieldStrictness -> m FieldStrictness
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> FieldStrictness -> m FieldStrictness
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> FieldStrictness -> m FieldStrictness
    Data, (forall x. FieldStrictness -> Rep FieldStrictness x)
    -> (forall x. Rep FieldStrictness x -> FieldStrictness)
    -> Generic FieldStrictness
    forall x. Rep FieldStrictness x -> FieldStrictness
    forall x. FieldStrictness -> Rep FieldStrictness x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. FieldStrictness -> Rep FieldStrictness x
    from :: forall x. FieldStrictness -> Rep FieldStrictness x
    $cto :: forall x. Rep FieldStrictness x -> FieldStrictness
    to :: forall x. Rep FieldStrictness x -> FieldStrictness
    Generic)

    -- | Information about a constructor field's unpackedness annotation.
    data Unpackedness
      = UnspecifiedUnpackedness -- ^ No annotation whatsoever
      | NoUnpack                -- ^ Annotated with @{\-\# NOUNPACK \#-\}@
      | Unpack                  -- ^ Annotated with @{\-\# UNPACK \#-\}@
      deriving (Int -> Unpackedness -> ShowS
    [Unpackedness] -> ShowS
    Unpackedness -> String
    (Int -> Unpackedness -> ShowS)
    -> (Unpackedness -> String)
    -> ([Unpackedness] -> ShowS)
    -> Show Unpackedness
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Unpackedness -> ShowS
    showsPrec :: Int -> Unpackedness -> ShowS
    $cshow :: Unpackedness -> String
    show :: Unpackedness -> String
    $cshowList :: [Unpackedness] -> ShowS
    showList :: [Unpackedness] -> ShowS
    Show, Unpackedness -> Unpackedness -> Bool
    (Unpackedness -> Unpackedness -> Bool)
    -> (Unpackedness -> Unpackedness -> Bool) -> Eq Unpackedness
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Unpackedness -> Unpackedness -> Bool
    == :: Unpackedness -> Unpackedness -> Bool
    $c/= :: Unpackedness -> Unpackedness -> Bool
    /= :: Unpackedness -> Unpackedness -> Bool
    Eq, Eq Unpackedness
    Eq Unpackedness =>
    (Unpackedness -> Unpackedness -> Ordering)
    -> (Unpackedness -> Unpackedness -> Bool)
    -> (Unpackedness -> Unpackedness -> Bool)
    -> (Unpackedness -> Unpackedness -> Bool)
    -> (Unpackedness -> Unpackedness -> Bool)
    -> (Unpackedness -> Unpackedness -> Unpackedness)
    -> (Unpackedness -> Unpackedness -> Unpackedness)
    -> Ord Unpackedness
    Unpackedness -> Unpackedness -> Bool
    Unpackedness -> Unpackedness -> Ordering
    Unpackedness -> Unpackedness -> Unpackedness
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Unpackedness -> Unpackedness -> Ordering
    compare :: Unpackedness -> Unpackedness -> Ordering
    $c< :: Unpackedness -> Unpackedness -> Bool
    < :: Unpackedness -> Unpackedness -> Bool
    $c<= :: Unpackedness -> Unpackedness -> Bool
    <= :: Unpackedness -> Unpackedness -> Bool
    $c> :: Unpackedness -> Unpackedness -> Bool
    > :: Unpackedness -> Unpackedness -> Bool
    $c>= :: Unpackedness -> Unpackedness -> Bool
    >= :: Unpackedness -> Unpackedness -> Bool
    $cmax :: Unpackedness -> Unpackedness -> Unpackedness
    max :: Unpackedness -> Unpackedness -> Unpackedness
    $cmin :: Unpackedness -> Unpackedness -> Unpackedness
    min :: Unpackedness -> Unpackedness -> Unpackedness
    Ord, Typeable Unpackedness
    Typeable Unpackedness =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Unpackedness -> c Unpackedness)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Unpackedness)
    -> (Unpackedness -> Constr)
    -> (Unpackedness -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Unpackedness))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c Unpackedness))
    -> ((forall b. Data b => b -> b) -> Unpackedness -> Unpackedness)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Unpackedness -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Unpackedness -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness)
    -> Data Unpackedness
    Unpackedness -> Constr
    Unpackedness -> DataType
    (forall b. Data b => b -> b) -> Unpackedness -> Unpackedness
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Unpackedness -> u
    forall u. (forall d. Data d => d -> u) -> Unpackedness -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Unpackedness
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Unpackedness -> c Unpackedness
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Unpackedness)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c Unpackedness)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Unpackedness -> c Unpackedness
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Unpackedness -> c Unpackedness
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Unpackedness
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Unpackedness
    $ctoConstr :: Unpackedness -> Constr
    toConstr :: Unpackedness -> Constr
    $cdataTypeOf :: Unpackedness -> DataType
    dataTypeOf :: Unpackedness -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Unpackedness)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Unpackedness)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c Unpackedness)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c Unpackedness)
    $cgmapT :: (forall b. Data b => b -> b) -> Unpackedness -> Unpackedness
    gmapT :: (forall b. Data b => b -> b) -> Unpackedness -> Unpackedness
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Unpackedness -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Unpackedness -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Unpackedness -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Unpackedness -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Unpackedness -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unpackedness -> m Unpackedness
    Data, (forall x. Unpackedness -> Rep Unpackedness x)
    -> (forall x. Rep Unpackedness x -> Unpackedness)
    -> Generic Unpackedness
    forall x. Rep Unpackedness x -> Unpackedness
    forall x. Unpackedness -> Rep Unpackedness x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Unpackedness -> Rep Unpackedness x
    from :: forall x. Unpackedness -> Rep Unpackedness x
    $cto :: forall x. Rep Unpackedness x -> Unpackedness
    to :: forall x. Rep Unpackedness x -> Unpackedness
    Generic)

    -- | Information about a constructor field's strictness annotation.
    data Strictness
      = UnspecifiedStrictness -- ^ No annotation whatsoever
      | Lazy                  -- ^ Annotated with @~@
      | Strict                -- ^ Annotated with @!@
      deriving (Int -> Strictness -> ShowS
    [Strictness] -> ShowS
    Strictness -> String
    (Int -> Strictness -> ShowS)
    -> (Strictness -> String)
    -> ([Strictness] -> ShowS)
    -> Show Strictness
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Strictness -> ShowS
    showsPrec :: Int -> Strictness -> ShowS
    $cshow :: Strictness -> String
    show :: Strictness -> String
    $cshowList :: [Strictness] -> ShowS
    showList :: [Strictness] -> ShowS
    Show, Strictness -> Strictness -> Bool
    (Strictness -> Strictness -> Bool)
    -> (Strictness -> Strictness -> Bool) -> Eq Strictness
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Strictness -> Strictness -> Bool
    == :: Strictness -> Strictness -> Bool
    $c/= :: Strictness -> Strictness -> Bool
    /= :: Strictness -> Strictness -> Bool
    Eq, Eq Strictness
    Eq Strictness =>
    (Strictness -> Strictness -> Ordering)
    -> (Strictness -> Strictness -> Bool)
    -> (Strictness -> Strictness -> Bool)
    -> (Strictness -> Strictness -> Bool)
    -> (Strictness -> Strictness -> Bool)
    -> (Strictness -> Strictness -> Strictness)
    -> (Strictness -> Strictness -> Strictness)
    -> Ord Strictness
    Strictness -> Strictness -> Bool
    Strictness -> Strictness -> Ordering
    Strictness -> Strictness -> Strictness
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Strictness -> Strictness -> Ordering
    compare :: Strictness -> Strictness -> Ordering
    $c< :: Strictness -> Strictness -> Bool
    < :: Strictness -> Strictness -> Bool
    $c<= :: Strictness -> Strictness -> Bool
    <= :: Strictness -> Strictness -> Bool
    $c> :: Strictness -> Strictness -> Bool
    > :: Strictness -> Strictness -> Bool
    $c>= :: Strictness -> Strictness -> Bool
    >= :: Strictness -> Strictness -> Bool
    $cmax :: Strictness -> Strictness -> Strictness
    max :: Strictness -> Strictness -> Strictness
    $cmin :: Strictness -> Strictness -> Strictness
    min :: Strictness -> Strictness -> Strictness
    Ord, Typeable Strictness
    Typeable Strictness =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Strictness -> c Strictness)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Strictness)
    -> (Strictness -> Constr)
    -> (Strictness -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Strictness))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c Strictness))
    -> ((forall b. Data b => b -> b) -> Strictness -> Strictness)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Strictness -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Strictness -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Strictness -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Strictness -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Strictness -> m Strictness)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Strictness -> m Strictness)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Strictness -> m Strictness)
    -> Data Strictness
    Strictness -> Constr
    Strictness -> DataType
    (forall b. Data b => b -> b) -> Strictness -> Strictness
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Strictness -> u
    forall u. (forall d. Data d => d -> u) -> Strictness -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Strictness -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Strictness -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Strictness -> m Strictness
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Strictness -> m Strictness
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Strictness
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Strictness -> c Strictness
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Strictness)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Strictness)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Strictness -> c Strictness
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Strictness -> c Strictness
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Strictness
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Strictness
    $ctoConstr :: Strictness -> Constr
    toConstr :: Strictness -> Constr
    $cdataTypeOf :: Strictness -> DataType
    dataTypeOf :: Strictness -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Strictness)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Strictness)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Strictness)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Strictness)
    $cgmapT :: (forall b. Data b => b -> b) -> Strictness -> Strictness
    gmapT :: (forall b. Data b => b -> b) -> Strictness -> Strictness
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Strictness -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Strictness -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Strictness -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Strictness -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Strictness -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Strictness -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Strictness -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Strictness -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Strictness -> m Strictness
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Strictness -> m Strictness
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Strictness -> m Strictness
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Strictness -> m Strictness
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Strictness -> m Strictness
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Strictness -> m Strictness
    Data, (forall x. Strictness -> Rep Strictness x)
    -> (forall x. Rep Strictness x -> Strictness) -> Generic Strictness
    forall x. Rep Strictness x -> Strictness
    forall x. Strictness -> Rep Strictness x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Strictness -> Rep Strictness x
    from :: forall x. Strictness -> Rep Strictness x
    $cto :: forall x. Rep Strictness x -> Strictness
    to :: forall x. Rep Strictness x -> Strictness
    Generic)

    isStrictAnnot, notStrictAnnot, unpackedAnnot :: FieldStrictness
    isStrictAnnot :: FieldStrictness
    isStrictAnnot  = Unpackedness -> Strictness -> FieldStrictness
    FieldStrictness Unpackedness
    UnspecifiedUnpackedness Strictness
    Strict
    notStrictAnnot :: FieldStrictness
    notStrictAnnot = Unpackedness -> Strictness -> FieldStrictness
    FieldStrictness Unpackedness
    UnspecifiedUnpackedness Strictness
    UnspecifiedStrictness
    unpackedAnnot :: FieldStrictness
    unpackedAnnot  = Unpackedness -> Strictness -> FieldStrictness
    FieldStrictness Unpackedness
    Unpack Strictness
    Strict

    -- | Construct a Type using the datatype's type constructor and type
    -- parameters. Kind signatures are removed.
    datatypeType :: DatatypeInfo -> Type
    datatypeType :: DatatypeInfo -> Type
    datatypeType DatatypeInfo
    di
      = (Type -> Type -> Type) -> Type -> [Type] -> Type
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Type -> Type -> Type
    AppT (Name -> Type
    ConT (DatatypeInfo -> Name
    datatypeName DatatypeInfo
    di))
      ([Type] -> Type) -> [Type] -> Type
    forall a b. (a -> b) -> a -> b
    $ (Type -> Type) -> [Type] -> [Type]
    forall a b. (a -> b) -> [a] -> [b]
    map Type -> Type
    stripSigT
      ([Type] -> [Type]) -> [Type] -> [Type]
    forall a b. (a -> b) -> a -> b
    $ DatatypeInfo -> [Type]
    datatypeInstTypes DatatypeInfo
    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 :: Name -> Q DatatypeInfo
    reifyDatatype Name
    n = String -> Bool -> Info -> Q DatatypeInfo
    normalizeInfo' String
    "reifyDatatype" Bool
    isReified (Info -> Q DatatypeInfo) -> Q Info -> Q DatatypeInfo
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Name -> Q Info
    reify Name
    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 :: Name -> Q ConstructorInfo
    reifyConstructor Name
    conName = do
      dataInfo <- Name -> Q DatatypeInfo
    reifyDatatype Name
    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 :: Name -> Q ConstructorInfo
    reifyRecord Name
    recordName = do
      dataInfo <- Name -> Q DatatypeInfo
    reifyDatatype Name
    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 :: Name -> DatatypeInfo -> ConstructorInfo
    lookupByConstructorName Name
    conName DatatypeInfo
    dataInfo =
      case (ConstructorInfo -> Bool)
    -> [ConstructorInfo] -> Maybe ConstructorInfo
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find ((Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    conName) (Name -> Bool)
    -> (ConstructorInfo -> Name) -> ConstructorInfo -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ConstructorInfo -> Name
    constructorName) (DatatypeInfo -> [ConstructorInfo]
    datatypeCons DatatypeInfo
    dataInfo) of
        Just ConstructorInfo
    conInfo -> ConstructorInfo
    conInfo
        Maybe ConstructorInfo
    Nothing      -> String -> ConstructorInfo
    forall a. HasCallStack => String -> a
    error (String -> ConstructorInfo) -> String -> ConstructorInfo
    forall a b. (a -> b) -> a -> b
    $ String
    "Datatype " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Name -> String
    nameBase (DatatypeInfo -> Name
    datatypeName DatatypeInfo
    dataInfo)
                             String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " does not have a constructor named " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Name -> String
    nameBase Name
    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 :: Name -> DatatypeInfo -> ConstructorInfo
    lookupByRecordName Name
    recordName DatatypeInfo
    dataInfo =
      case (ConstructorInfo -> Bool)
    -> [ConstructorInfo] -> Maybe ConstructorInfo
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find (Name -> ConstructorInfo -> Bool
    conHasRecord Name
    recordName) (DatatypeInfo -> [ConstructorInfo]
    datatypeCons DatatypeInfo
    dataInfo) of
        Just ConstructorInfo
    conInfo -> ConstructorInfo
    conInfo
        Maybe ConstructorInfo
    Nothing      -> String -> ConstructorInfo
    forall a. HasCallStack => String -> a
    error (String -> ConstructorInfo) -> String -> ConstructorInfo
    forall a b. (a -> b) -> a -> b
    $ String
    "Datatype " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Name -> String
    nameBase (DatatypeInfo -> Name
    datatypeName DatatypeInfo
    dataInfo)
                             String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " does not have any constructors with a "
                             String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "record selector named " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Name -> String
    nameBase Name
    recordName

    -- | Normalize 'Info' for a newtype or datatype into a 'DatatypeInfo'.
    -- Fail in 'Q' otherwise.
    normalizeInfo :: Info -> Q DatatypeInfo
    normalizeInfo :: Info -> Q DatatypeInfo
    normalizeInfo = String -> Bool -> Info -> Q DatatypeInfo
    normalizeInfo' String
    "normalizeInfo" Bool
    isn'tReified

    normalizeInfo' :: String -> IsReifiedDec -> Info -> Q DatatypeInfo
    normalizeInfo' :: String -> Bool -> Info -> Q DatatypeInfo
    normalizeInfo' String
    entry Bool
    reifiedDec Info
    i =
      case Info
    i of
        (PrimTyConI Name
    name Int
    arity Bool
    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.
          Bool -> Dec -> Q DatatypeInfo
    normalizeDecFor Bool
    reifiedDec (Dec -> Q DatatypeInfo) -> Dec -> Q DatatypeInfo
    forall a b. (a -> b) -> a -> b
    $ [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> [Con]
    -> [DerivClause]
    -> Dec
    DataD [] Name
    name [] Maybe Type
    forall a. Maybe a
    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{}                          -> String -> Q DatatypeInfo
    forall {m :: * -> *} {a}. MonadFail m => String -> m a
    bad String
    "Class not supported"
        FamilyI DataFamilyD{} [Dec]
    _           -> String -> Q DatatypeInfo
    forall {m :: * -> *} {a}. MonadFail m => String -> m a
    bad String
    "Use a value constructor to reify a data family instance"
        FamilyI Dec
    _ [Dec]
    _                       -> String -> Q DatatypeInfo
    forall {m :: * -> *} {a}. MonadFail m => String -> m a
    bad String
    "Type families not supported"
        TyConI Dec
    dec                        -> Bool -> Dec -> Q DatatypeInfo
    normalizeDecFor Bool
    reifiedDec Dec
    dec
        DataConI Name
    name Type
    _ Name
    parent            -> Name -> Name -> Q DatatypeInfo
    reifyParent Name
    name 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 Name
    recName Type
    recTy Maybe Dec
    _              -> Name -> Type -> Q DatatypeInfo
    reifyRecordType Name
    recName Type
    recTy
                                             -- NB: Similarly, we do not pass the IsReifiedDec
                                             -- information here.
        Info
    _                                 -> String -> Q DatatypeInfo
    forall {m :: * -> *} {a}. MonadFail m => String -> m a
    bad String
    "Expected a type constructor"
      where
        bad :: String -> m a
    bad String
    msg = String -> m a
    forall a. String -> m a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String
    entry String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    ": " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    msg)

    reifyParent :: Name -> Name -> Q DatatypeInfo
    reifyParent :: Name -> Name -> Q DatatypeInfo
    reifyParent Name
    con = String -> (DatatypeInfo -> Bool) -> Name -> Q DatatypeInfo
    reifyParentWith String
    "reifyParent" DatatypeInfo -> Bool
    p
      where
        p :: DatatypeInfo -> Bool
        p :: DatatypeInfo -> Bool
    p DatatypeInfo
    info = Name
    con Name -> [Name] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` (ConstructorInfo -> Name) -> [ConstructorInfo] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map ConstructorInfo -> Name
    constructorName (DatatypeInfo -> [ConstructorInfo]
    datatypeCons DatatypeInfo
    info)

    reifyRecordType :: Name -> Type -> Q DatatypeInfo
    reifyRecordType :: Name -> Type -> Q DatatypeInfo
    reifyRecordType Name
    recName Type
    recTy =
      let ([TyVarBndrSpec]
    _, [Type]
    _, [Type]
    argTys :|- Type
    _) = Type -> ([TyVarBndrSpec], [Type], NonEmptySnoc Type)
    uncurryType Type
    recTy
      in case [Type]
    argTys of
           Type
    dataTy:[Type]
    _ -> Type -> Q DatatypeInfo
    decomposeDataType Type
    dataTy
           [Type]
    _        -> Q DatatypeInfo
    forall a. Q a
    notRecSelFailure
      where
        decomposeDataType :: Type -> Q DatatypeInfo
        decomposeDataType :: Type -> Q DatatypeInfo
    decomposeDataType Type
    ty =
          do case Type -> NonEmpty Type
    decomposeType Type
    ty of
               ConT Name
    parent :| [Type]
    _ -> String -> (DatatypeInfo -> Bool) -> Name -> Q DatatypeInfo
    reifyParentWith String
    "reifyRecordType" DatatypeInfo -> Bool
    p Name
    parent
               NonEmpty Type
    _                -> Q DatatypeInfo
    forall a. Q a
    notRecSelFailure

        notRecSelFailure :: Q a
        notRecSelFailure :: forall a. Q a
    notRecSelFailure = String -> Q a
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q a) -> String -> Q a
    forall a b. (a -> b) -> a -> b
    $
          String
    "reifyRecordType: Not a record selector type: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
          Name -> String
    nameBase Name
    recName String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " :: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Type -> String
    forall a. Show a => a -> String
    show Type
    recTy

        p :: DatatypeInfo -> Bool
        p :: DatatypeInfo -> Bool
    p DatatypeInfo
    info = (ConstructorInfo -> Bool) -> [ConstructorInfo] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Name -> ConstructorInfo -> Bool
    conHasRecord Name
    recName) (DatatypeInfo -> [ConstructorInfo]
    datatypeCons DatatypeInfo
    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 :: String -> (DatatypeInfo -> Bool) -> Name -> Q DatatypeInfo
    reifyParentWith String
    prefix DatatypeInfo -> Bool
    p Name
    n =
      do info <- Name -> Q Info
    reify Name
    n
         case info of
           TyConI Dec
    dec -> Bool -> Dec -> Q DatatypeInfo
    normalizeDecFor Bool
    isReified Dec
    dec
           FamilyI Dec
    dec [Dec]
    instances ->
             do instances1 <- (Dec -> Q Dec) -> [Dec] -> Q [Dec]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (Dec -> Dec -> Q Dec
    repairDataFam Dec
    dec) [Dec]
    instances
                instances2 <- mapM (normalizeDecFor isReified) instances1
                case find p instances2 of
                  Just DatatypeInfo
    inst -> DatatypeInfo -> Q DatatypeInfo
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return DatatypeInfo
    inst
                  Maybe DatatypeInfo
    Nothing   -> String -> Q DatatypeInfo
    forall a. String -> Q a
    panic String
    "lost the instance"
           Info
    _ -> String -> Q DatatypeInfo
    forall a. String -> Q a
    panic String
    "unexpected parent"
      where
        dataFamiliesOnOldGHCsError :: Q a
        dataFamiliesOnOldGHCsError :: forall a. Q a
    dataFamiliesOnOldGHCsError = String -> Q a
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q a) -> String -> Q a
    forall a b. (a -> b) -> a -> b
    $
          String
    prefix String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    ": Data family instances can only be reified with GHC 7.4 or later"

        panic :: String -> Q a
        panic :: forall a. String -> Q a
    panic String
    message = String -> Q a
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q a) -> String -> Q a
    forall a b. (a -> b) -> a -> b
    $ String
    "PANIC: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    prefix String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    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 :: Dec -> Dec -> Q Dec
    repairDataFam Dec
    famD Dec
    instD
    #if MIN_VERSION_template_haskell(2,15,0)
          | DataFamilyD Name
    _ [TyVarBndr BndrVis]
    dvars Maybe Type
    dk <- Dec
    famD
          , NewtypeInstD [Type]
    cx Maybe [TyVarBndrUnit]
    mbInstVars Type
    nts Maybe Type
    k Con
    c [DerivClause]
    deriv <- Dec
    instD
          , Type
    con :| [Type]
    ts <- Type -> NonEmpty Type
    decomposeType Type
    nts
          = do ts' <- [TyVarBndr BndrVis] -> Maybe Type -> [Type] -> Q [Type]
    repairVarKindsWith [TyVarBndr BndrVis]
    dvars Maybe Type
    dk [Type]
    ts
               return $ NewtypeInstD cx mbInstVars (foldl' AppT con ts') k c deriv

          | DataFamilyD Name
    _ [TyVarBndr BndrVis]
    dvars Maybe Type
    dk <- Dec
    famD
          , DataInstD [Type]
    cx Maybe [TyVarBndrUnit]
    mbInstVars Type
    nts Maybe Type
    k [Con]
    c [DerivClause]
    deriv <- Dec
    instD
          , Type
    con :| [Type]
    ts <- Type -> NonEmpty Type
    decomposeType Type
    nts
          = do ts' <- [TyVarBndr BndrVis] -> Maybe Type -> [Type] -> Q [Type]
    repairVarKindsWith [TyVarBndr BndrVis]
    dvars Maybe Type
    dk [Type]
    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 Dec
    _ Dec
    instD = Dec -> Q Dec
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Dec
    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 :: [TyVarBndr BndrVis] -> Maybe Type -> [Type] -> Q [Type]
    repairVarKindsWith [TyVarBndr BndrVis]
    tvbs Maybe Type
    mbKind [Type]
    ts = do
      extra_tvbs <- Type -> Q [TyVarBndrUnit]
    mkExtraKindBinders (Type -> Q [TyVarBndrUnit]) -> Type -> Q [TyVarBndrUnit]
    forall a b. (a -> b) -> a -> b
    $ Type -> Maybe Type -> Type
    forall a. a -> Maybe a -> a
    fromMaybe Type
    starK Maybe Type
    mbKind
      -- This list should be the same length as @ts@. If it isn't, something has
      -- gone terribly wrong.
      let tvbs' = () -> [TyVarBndr BndrVis] -> [TyVarBndrUnit]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags () [TyVarBndr BndrVis]
    tvbs [TyVarBndrUnit] -> [TyVarBndrUnit] -> [TyVarBndrUnit]
    forall a. [a] -> [a] -> [a]
    ++ [TyVarBndrUnit]
    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 :: forall flag. TyVarBndr_ flag -> Type -> Type
    stealKindForType TyVarBndr_ flag
    tvb t :: Type
    t@VarT{} = Type -> Type -> Type
    SigT Type
    t (TyVarBndr_ flag -> Type
    forall flag. TyVarBndr_ flag -> Type
    tvKind TyVarBndr_ flag
    tvb)
    stealKindForType TyVarBndr_ flag
    _   Type
    t        = Type
    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 :: Dec -> Q DatatypeInfo
    normalizeDec = Bool -> Dec -> Q DatatypeInfo
    normalizeDecFor Bool
    isn'tReified

    normalizeDecFor :: IsReifiedDec -> Dec -> Q DatatypeInfo
    normalizeDecFor :: Bool -> Dec -> Q DatatypeInfo
    normalizeDecFor Bool
    isReified Dec
    dec =
      case Dec
    dec of
    #if MIN_VERSION_template_haskell(2,20,0)
        TypeDataD Name
    name [TyVarBndr BndrVis]
    tyvars Maybe Type
    mbKind [Con]
    cons ->
          [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDataD [] Name
    name [TyVarBndr BndrVis]
    tyvars Maybe Type
    mbKind [Con]
    cons DatatypeVariant
    TypeData
    #endif
    #if MIN_VERSION_template_haskell(2,12,0)
        NewtypeD [Type]
    context Name
    name [TyVarBndr BndrVis]
    tyvars Maybe Type
    mbKind Con
    con [DerivClause]
    _derives ->
          [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDataD [Type]
    context Name
    name [TyVarBndr BndrVis]
    tyvars Maybe Type
    mbKind [Con
    con] DatatypeVariant
    Newtype
        DataD [Type]
    context Name
    name [TyVarBndr BndrVis]
    tyvars Maybe Type
    mbKind [Con]
    cons [DerivClause]
    _derives ->
          [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDataD [Type]
    context Name
    name [TyVarBndr BndrVis]
    tyvars Maybe Type
    mbKind [Con]
    cons DatatypeVariant
    Datatype
    # if MIN_VERSION_template_haskell(2,15,0)
        NewtypeInstD [Type]
    context Maybe [TyVarBndrUnit]
    mbTyvars Type
    nameInstTys Maybe Type
    mbKind Con
    con [DerivClause]
    _derives ->
          String
    -> [Type]
    -> Maybe [TyVarBndrUnit]
    -> Type
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDataInstDPostTH2'15 String
    "newtype" [Type]
    context Maybe [TyVarBndrUnit]
    mbTyvars Type
    nameInstTys
                                       Maybe Type
    mbKind [Con
    con] DatatypeVariant
    NewtypeInstance
        DataInstD [Type]
    context Maybe [TyVarBndrUnit]
    mbTyvars Type
    nameInstTys Maybe Type
    mbKind [Con]
    cons [DerivClause]
    _derives ->
          String
    -> [Type]
    -> Maybe [TyVarBndrUnit]
    -> Type
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDataInstDPostTH2'15 String
    "data" [Type]
    context Maybe [TyVarBndrUnit]
    mbTyvars Type
    nameInstTys
                                       Maybe Type
    mbKind [Con]
    cons DatatypeVariant
    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
        Dec
    _ -> String -> Q DatatypeInfo
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "normalizeDecFor: DataD or NewtypeD required"
      where
        -- We only need to repair reified declarations for data family instances.
        repair13618' :: DatatypeInfo -> Q DatatypeInfo
        repair13618' :: DatatypeInfo -> Q DatatypeInfo
    repair13618' di :: DatatypeInfo
    di@DatatypeInfo{datatypeVariant :: DatatypeInfo -> DatatypeVariant
    datatypeVariant = DatatypeVariant
    variant}
          | Bool
    isReified Bool -> Bool -> Bool
    && DatatypeVariant -> Bool
    isFamInstVariant DatatypeVariant
    variant
          = DatatypeInfo -> Q DatatypeInfo
    repair13618 DatatypeInfo
    di
          | Bool
    otherwise
          = DatatypeInfo -> Q DatatypeInfo
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return DatatypeInfo
    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 -> [Type] -> Maybe Type -> Q (Maybe Type)
    normalizeMbKind Name
    _name [Type]
    _instTys mbKind :: Maybe Type
    mbKind@(Just Type
    _) = Maybe Type -> Q (Maybe Type)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Type
    mbKind
        normalizeMbKind Name
    name [Type]
    instTys Maybe Type
    Nothing = do
    #if MIN_VERSION_template_haskell(2,16,0)
          mbReifiedKind <- Maybe Type -> Q (Maybe Type)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Type
    forall a. Maybe a
    Nothing Q (Maybe Type) -> Q (Maybe Type) -> Q (Maybe Type)
    forall a. Q a -> Q a -> Q a
    `recover` (Type -> Maybe Type) -> Q Type -> Q (Maybe Type)
    forall a b. (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Type -> Maybe Type
    forall a. a -> Maybe a
    Just (Name -> Q Type
    reifyType Name
    name)
          T.mapM normalizeKind mbReifiedKind
          where
            normalizeKind :: Kind -> Q Kind
            normalizeKind :: Type -> Q Type
    normalizeKind Type
    k = do
              k' <- Type -> Q Type
    resolveKindSynonyms Type
    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
                      (\(Type
    instTy, VisFunArg
    arg) ->
                        case VisFunArg
    arg of
                          VisFADep TyVarBndrUnit
    tvb -> (Type, Type) -> Maybe (Type, Type)
    forall a. a -> Maybe a
    Just (Type
    instTy, TyVarBndrUnit -> Type
    forall flag. TyVarBndr_ flag -> Type
    bndrParam TyVarBndrUnit
    tvb)
                          VisFAAnon Type
    k  -> (, Type
    k) (Type -> (Type, Type)) -> Maybe Type -> Maybe (Type, Type)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Maybe Type
    sigTMaybeKind Type
    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 :: forall flag.
    [TyVarBndr_ flag] -> FunArgs -> Type -> [TyVarBndrUnit]
    datatypeFreeVars [TyVarBndr_ flag]
    declBndrs FunArgs
    kindArgs Type
    kindRes =
          [Type] -> [TyVarBndrUnit]
    freeVariablesWellScoped ([Type] -> [TyVarBndrUnit]) -> [Type] -> [TyVarBndrUnit]
    forall a b. (a -> b) -> a -> b
    $
          [TyVarBndr_ flag] -> [Type]
    forall flag. [TyVarBndr_ flag] -> [Type]
    bndrParams [TyVarBndr_ flag]
    declBndrs [Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++ FunArgs -> [Type]
    funArgTys FunArgs
    kindArgs [Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++ [Type
    kindRes]

        normalizeDataD :: Cxt -> Name -> [TyVarBndrVis] -> Maybe Kind
                       -> [Con] -> DatatypeVariant -> Q DatatypeInfo
        normalizeDataD :: [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDataD [Type]
    context Name
    name [TyVarBndr BndrVis]
    tyvars Maybe Type
    mbKind [Con]
    cons DatatypeVariant
    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 :: [Type]
    tys = [TyVarBndr BndrVis] -> [Type]
    forall flag. [TyVarBndr_ flag] -> [Type]
    bndrParams ([TyVarBndr BndrVis] -> [Type]) -> [TyVarBndr BndrVis] -> [Type]
    forall a b. (a -> b) -> a -> b
    $ (TyVarBndr BndrVis -> Bool)
    -> [TyVarBndr BndrVis] -> [TyVarBndr BndrVis]
    forall a. (a -> Bool) -> [a] -> [a]
    filter TyVarBndr BndrVis -> Bool
    isRequiredTvb [TyVarBndr BndrVis]
    tyvars
          mbKind' <- Name -> [Type] -> Maybe Type -> Q (Maybe Type)
    normalizeMbKind Name
    name [Type]
    tys Maybe Type
    mbKind
          normalize' context name tyvars tys mbKind' cons variant

        normalizeDataInstDPostTH2'15
          :: String -> Cxt -> Maybe [TyVarBndrUnit] -> Type -> Maybe Kind
          -> [Con] -> DatatypeVariant -> Q DatatypeInfo
        normalizeDataInstDPostTH2'15 :: String
    -> [Type]
    -> Maybe [TyVarBndrUnit]
    -> Type
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDataInstDPostTH2'15 String
    what [Type]
    context Maybe [TyVarBndrUnit]
    mbTyvars Type
    nameInstTys
                                     Maybe Type
    mbKind [Con]
    cons DatatypeVariant
    variant =
          case Type -> NonEmpty Type
    decomposeType Type
    nameInstTys of
            ConT Name
    name :| [Type]
    instTys -> do
              mbKind' <- Name -> [Type] -> Maybe Type -> Q (Maybe Type)
    normalizeMbKind Name
    name [Type]
    instTys Maybe Type
    mbKind
              normalize' context name
                         (fromMaybe (freeVariablesWellScoped instTys) mbTyvars)
                         instTys mbKind' cons variant
            NonEmpty Type
    _ -> String -> Q DatatypeInfo
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q DatatypeInfo) -> String -> Q DatatypeInfo
    forall a b. (a -> b) -> a -> b
    $ String
    "Unexpected " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    what String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " instance head: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Type -> String
    forall a. Ppr a => a -> String
    pprint Type
    nameInstTys

        normalizeDataInstDPreTH2'15
          :: Cxt -> Name -> [Type] -> Maybe Kind
          -> [Con] -> DatatypeVariant -> Q DatatypeInfo
        normalizeDataInstDPreTH2'15 :: [Type]
    -> Name
    -> [Type]
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDataInstDPreTH2'15 [Type]
    context Name
    name [Type]
    instTys Maybe Type
    mbKind [Con]
    cons DatatypeVariant
    variant = do
          mbKind' <- Name -> [Type] -> Maybe Type -> Q (Maybe Type)
    normalizeMbKind Name
    name [Type]
    instTys Maybe Type
    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' :: forall flag.
    [Type]
    -> Name
    -> [TyVarBndr_ flag]
    -> [Type]
    -> Maybe Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalize' [Type]
    context Name
    name [TyVarBndr_ flag]
    tvbs [Type]
    instTys Maybe Type
    mbKind [Con]
    cons DatatypeVariant
    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 :: Type
    kind = Type -> Maybe Type -> Type
    forall a. a -> Maybe a -> a
    fromMaybe Type
    starK Maybe Type
    mbKind
          kind' <- Type -> Q Type
    resolveKindSynonyms Type
    kind
          let (kindArgs, kindRes) = unravelType kind'
          (extra_vis_tvbs, kindArgs') <- mkExtraFunArgForalls kindArgs
          let tvbs'    = [TyVarBndr_ flag] -> FunArgs -> Type -> [TyVarBndrUnit]
    forall flag.
    [TyVarBndr_ flag] -> FunArgs -> Type -> [TyVarBndrUnit]
    datatypeFreeVars [TyVarBndr_ flag]
    tvbs FunArgs
    kindArgs' Type
    kindRes
              instTys' = [Type]
    instTys [Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++ [TyVarBndrUnit] -> [Type]
    forall flag. [TyVarBndr_ flag] -> [Type]
    bndrParams [TyVarBndrUnit]
    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 :: Type -> Q [TyVarBndrUnit]
    mkExtraKindBinders Type
    kind = do
      kind' <- Type -> Q Type
    resolveKindSynonyms Type
    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 :: FunArgs -> Q ([TyVarBndrUnit], FunArgs)
    mkExtraFunArgForalls FunArgs
    FANil =
      ([TyVarBndrUnit], FunArgs) -> Q ([TyVarBndrUnit], FunArgs)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([], FunArgs
    FANil)
    mkExtraFunArgForalls (FAForalls ForallTelescope
    tele FunArgs
    args) = do
      (extra_vis_tvbs', args') <- FunArgs -> Q ([TyVarBndrUnit], FunArgs)
    mkExtraFunArgForalls FunArgs
    args
      case tele of
        ForallVis [TyVarBndrUnit]
    tvbs ->
          ([TyVarBndrUnit], FunArgs) -> Q ([TyVarBndrUnit], FunArgs)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ( [TyVarBndrUnit]
    tvbs [TyVarBndrUnit] -> [TyVarBndrUnit] -> [TyVarBndrUnit]
    forall a. [a] -> [a] -> [a]
    ++ [TyVarBndrUnit]
    extra_vis_tvbs'
                 , ForallTelescope -> FunArgs -> FunArgs
    FAForalls ([TyVarBndrUnit] -> ForallTelescope
    ForallVis [TyVarBndrUnit]
    tvbs) FunArgs
    args'
                 )
        ForallInvis [TyVarBndrSpec]
    tvbs ->
          ([TyVarBndrUnit], FunArgs) -> Q ([TyVarBndrUnit], FunArgs)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ( [TyVarBndrUnit]
    extra_vis_tvbs'
                 , ForallTelescope -> FunArgs -> FunArgs
    FAForalls ([TyVarBndrSpec] -> ForallTelescope
    ForallInvis [TyVarBndrSpec]
    tvbs) FunArgs
    args'
                 )
    mkExtraFunArgForalls (FACxt [Type]
    ctxt FunArgs
    args) = do
      (extra_vis_tvbs', args') <- FunArgs -> Q ([TyVarBndrUnit], FunArgs)
    mkExtraFunArgForalls FunArgs
    args
      return (extra_vis_tvbs', FACxt ctxt args')
    mkExtraFunArgForalls (FAAnon Type
    anon FunArgs
    args) = do
      name <- String -> Q Name
    forall (m :: * -> *). Quote m => String -> m Name
    newName String
    "x"
      let tvb = Name -> Type -> TyVarBndrUnit
    forall flag. DefaultBndrFlag flag => Name -> Type -> TyVarBndr flag
    kindedTV Name
    name Type
    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 :: DatatypeVariant -> Bool
    isFamInstVariant DatatypeVariant
    dv =
      case DatatypeVariant
    dv of
        DatatypeVariant
    Datatype        -> Bool
    False
        DatatypeVariant
    Newtype         -> Bool
    False
        DatatypeVariant
    DataInstance    -> Bool
    True
        DatatypeVariant
    NewtypeInstance -> Bool
    True
        DatatypeVariant
    TypeData        -> Bool
    False

    bndrParams :: [TyVarBndr_ flag] -> [Type]
    bndrParams :: forall flag. [TyVarBndr_ flag] -> [Type]
    bndrParams = (TyVarBndr_ flag -> Type) -> [TyVarBndr_ flag] -> [Type]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr_ flag -> Type
    forall flag. TyVarBndr_ flag -> Type
    bndrParam

    bndrParam :: TyVarBndr_ flag -> Type
    bndrParam :: forall flag. TyVarBndr_ flag -> Type
    bndrParam = (Name -> Type) -> (Name -> Type -> Type) -> TyVarBndr_ flag -> Type
    forall r flag.
    (Name -> r) -> (Name -> Type -> r) -> TyVarBndr_ flag -> r
    elimTV Name -> Type
    VarT (\Name
    n Type
    k -> Type -> Type -> Type
    SigT (Name -> Type
    VarT Name
    n) Type
    k)

    -- | Returns 'True' if the flag of the supplied 'TyVarBndrVis' is 'BndrReq'.
    isRequiredTvb :: TyVarBndrVis -> Bool
    isRequiredTvb :: TyVarBndr BndrVis -> Bool
    isRequiredTvb TyVarBndr BndrVis
    tvb = TyVarBndr BndrVis -> BndrVis
    forall flag. TyVarBndr_ flag -> flag
    tvFlag TyVarBndr BndrVis
    tvb BndrVis -> BndrVis -> Bool
    forall a. Eq a => a -> a -> Bool
    == BndrVis
    BndrReq

    -- | Remove the outermost 'SigT'.
    stripSigT :: Type -> Type
    stripSigT :: Type -> Type
    stripSigT (SigT Type
    t Type
    _) = Type
    t
    stripSigT Type
    t          = Type
    t

    -- | If the supplied 'Type' is a @'SigT' _ k@, return @'Just' k@. Otherwise,
    -- return 'Nothing'.
    sigTMaybeKind :: Type -> Maybe Kind
    sigTMaybeKind :: Type -> Maybe Type
    sigTMaybeKind (SigT Type
    _ Type
    k) = Type -> Maybe Type
    forall a. a -> Maybe a
    Just Type
    k
    sigTMaybeKind Type
    _          = Maybe Type
    forall a. Maybe a
    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' :: Bool
    -> [Type]
    -> Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> Type
    -> [Con]
    -> DatatypeVariant
    -> Q DatatypeInfo
    normalizeDec' Bool
    reifiedDec [Type]
    context Name
    name [TyVarBndrUnit]
    params [Type]
    instTys Type
    resKind [Con]
    cons DatatypeVariant
    variant =
      do cons' <- [[ConstructorInfo]] -> [ConstructorInfo]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[ConstructorInfo]] -> [ConstructorInfo])
    -> Q [[ConstructorInfo]] -> Q [ConstructorInfo]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Con -> Q [ConstructorInfo]) -> [Con] -> Q [[ConstructorInfo]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (Bool
    -> Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> Type
    -> DatatypeVariant
    -> Con
    -> Q [ConstructorInfo]
    normalizeConFor Bool
    reifiedDec Name
    name [TyVarBndrUnit]
    params [Type]
    instTys Type
    resKind DatatypeVariant
    variant) [Con]
    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 :: Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> Type
    -> DatatypeVariant
    -> Con
    -> Q [ConstructorInfo]
    normalizeCon = Bool
    -> Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> Type
    -> DatatypeVariant
    -> Con
    -> Q [ConstructorInfo]
    normalizeConFor Bool
    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 :: Bool
    -> Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> Type
    -> DatatypeVariant
    -> Con
    -> Q [ConstructorInfo]
    normalizeConFor Bool
    reifiedDec Name
    typename [TyVarBndrUnit]
    params [Type]
    instTys Type
    resKind DatatypeVariant
    variant =
      ([ConstructorInfo] -> [ConstructorInfo])
    -> Q [ConstructorInfo] -> Q [ConstructorInfo]
    forall a b. (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((ConstructorInfo -> ConstructorInfo)
    -> [ConstructorInfo] -> [ConstructorInfo]
    forall a b. (a -> b) -> [a] -> [b]
    map (Bool -> ConstructorInfo -> ConstructorInfo
    giveCIVarsStarKinds Bool
    reifiedDec)) (Q [ConstructorInfo] -> Q [ConstructorInfo])
    -> (Con -> Q [ConstructorInfo]) -> Con -> Q [ConstructorInfo]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Con -> Q [ConstructorInfo]
    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 :: [Type] -> Name -> Q ConstructorVariant
    checkGadtFixity [Type]
    ts Name
    n = do
          -- Don't call reifyFixityCompat here! We need to be able to distinguish
          -- between a default fixity and an explicit @infixl 9@.
          mbFi <- Maybe Fixity -> Q (Maybe Fixity)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Fixity
    forall a. Maybe a
    Nothing Q (Maybe Fixity) -> Q (Maybe Fixity) -> Q (Maybe Fixity)
    forall a. Q a -> Q a -> Q a
    `recover` Name -> Q (Maybe Fixity)
    reifyFixity Name
    n
          let userSuppliedFixity = Maybe Fixity -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe Fixity
    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 :: String -> Bool
    isInfixDataCon (Char
    ':':String
    _) = Bool
    True
        isInfixDataCon String
    _       = Bool
    False

        dispatch :: Con -> Q [ConstructorInfo]
        dispatch :: Con -> Q [ConstructorInfo]
    dispatch =
          let defaultCase :: Con -> Q [ConstructorInfo]
              defaultCase :: Con -> Q [ConstructorInfo]
    defaultCase = [TyVarBndrUnit] -> [Type] -> Bool -> Con -> Q [ConstructorInfo]
    go [] [] Bool
    False
                where
                  go :: [TyVarBndrUnit]
                     -> Cxt
                     -> Bool -- Is this a GADT? (see the documentation for
                             -- for checkGadtFixity)
                     -> Con
                     -> Q [ConstructorInfo]
                  go :: [TyVarBndrUnit] -> [Type] -> Bool -> Con -> Q [ConstructorInfo]
    go [TyVarBndrUnit]
    tyvars [Type]
    context Bool
    gadt Con
    c =
                    case Con
    c of
                      NormalC Name
    n [BangType]
    xs -> do
                        let ([Bang]
    bangs, [Type]
    ts) = [BangType] -> ([Bang], [Type])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [BangType]
    xs
                            stricts :: [FieldStrictness]
    stricts     = (Bang -> FieldStrictness) -> [Bang] -> [FieldStrictness]
    forall a b. (a -> b) -> [a] -> [b]
    map Bang -> FieldStrictness
    normalizeStrictness [Bang]
    bangs
                        fi <- if Bool
    gadt
                                 then [Type] -> Name -> Q ConstructorVariant
    checkGadtFixity [Type]
    ts Name
    n
                                 else ConstructorVariant -> Q ConstructorVariant
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ConstructorVariant
    NormalConstructor
                        return [ConstructorInfo n tyvars context ts stricts fi]
                      InfixC BangType
    l Name
    n BangType
    r ->
                        let ([Bang]
    bangs, [Type]
    ts) = [BangType] -> ([Bang], [Type])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [BangType
    l,BangType
    r]
                            stricts :: [FieldStrictness]
    stricts     = (Bang -> FieldStrictness) -> [Bang] -> [FieldStrictness]
    forall a b. (a -> b) -> [a] -> [b]
    map Bang -> FieldStrictness
    normalizeStrictness [Bang]
    bangs in
                        [ConstructorInfo] -> Q [ConstructorInfo]
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> [Type]
    -> [FieldStrictness]
    -> ConstructorVariant
    -> ConstructorInfo
    ConstructorInfo Name
    n [TyVarBndrUnit]
    tyvars [Type]
    context [Type]
    ts [FieldStrictness]
    stricts
                                                ConstructorVariant
    InfixConstructor]
                      RecC Name
    n [VarBangType]
    xs ->
                        let fns :: [Name]
    fns     = [VarBangType] -> [Name]
    forall a b. [(Name, a, b)] -> [Name]
    takeFieldNames [VarBangType]
    xs
                            stricts :: [FieldStrictness]
    stricts = [VarBangType] -> [FieldStrictness]
    forall a b. [(a, Bang, b)] -> [FieldStrictness]
    takeFieldStrictness [VarBangType]
    xs in
                        [ConstructorInfo] -> Q [ConstructorInfo]
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> [Type]
    -> [FieldStrictness]
    -> ConstructorVariant
    -> ConstructorInfo
    ConstructorInfo Name
    n [TyVarBndrUnit]
    tyvars [Type]
    context
                                  ([VarBangType] -> [Type]
    forall a b. [(a, b, Type)] -> [Type]
    takeFieldTypes [VarBangType]
    xs) [FieldStrictness]
    stricts ([Name] -> ConstructorVariant
    RecordConstructor [Name]
    fns)]
                      ForallC [TyVarBndrSpec]
    tyvars' [Type]
    context' Con
    c' ->
                        [TyVarBndrUnit] -> [Type] -> Bool -> Con -> Q [ConstructorInfo]
    go (() -> [TyVarBndrSpec] -> [TyVarBndrUnit]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags () [TyVarBndrSpec]
    tyvars'[TyVarBndrUnit] -> [TyVarBndrUnit] -> [TyVarBndrUnit]
    forall a. [a] -> [a] -> [a]
    ++[TyVarBndrUnit]
    tyvars) ([Type]
    context'[Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++[Type]
    context) Bool
    True Con
    c'
                      GadtC [Name]
    ns [BangType]
    xs Type
    innerType ->
                        let ([Bang]
    bangs, [Type]
    ts) = [BangType] -> ([Bang], [Type])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [BangType]
    xs
                            stricts :: [FieldStrictness]
    stricts     = (Bang -> FieldStrictness) -> [Bang] -> [FieldStrictness]
    forall a b. (a -> b) -> [a] -> [b]
    map Bang -> FieldStrictness
    normalizeStrictness [Bang]
    bangs in
                        [Name]
    -> Type
    -> [Type]
    -> [FieldStrictness]
    -> (Name -> Q ConstructorVariant)
    -> Q [ConstructorInfo]
    gadtCase [Name]
    ns Type
    innerType [Type]
    ts [FieldStrictness]
    stricts ([Type] -> Name -> Q ConstructorVariant
    checkGadtFixity [Type]
    ts)
                      RecGadtC [Name]
    ns [VarBangType]
    xs Type
    innerType ->
                        let fns :: [Name]
    fns     = [VarBangType] -> [Name]
    forall a b. [(Name, a, b)] -> [Name]
    takeFieldNames [VarBangType]
    xs
                            stricts :: [FieldStrictness]
    stricts = [VarBangType] -> [FieldStrictness]
    forall a b. [(a, Bang, b)] -> [FieldStrictness]
    takeFieldStrictness [VarBangType]
    xs in
                        [Name]
    -> Type
    -> [Type]
    -> [FieldStrictness]
    -> (Name -> Q ConstructorVariant)
    -> Q [ConstructorInfo]
    gadtCase [Name]
    ns Type
    innerType ([VarBangType] -> [Type]
    forall a b. [(a, b, Type)] -> [Type]
    takeFieldTypes [VarBangType]
    xs) [FieldStrictness]
    stricts
                                 (Q ConstructorVariant -> Name -> Q ConstructorVariant
    forall a b. a -> b -> a
    const (Q ConstructorVariant -> Name -> Q ConstructorVariant)
    -> Q ConstructorVariant -> Name -> Q ConstructorVariant
    forall a b. (a -> b) -> a -> b
    $ ConstructorVariant -> Q ConstructorVariant
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ConstructorVariant -> Q ConstructorVariant)
    -> ConstructorVariant -> Q ConstructorVariant
    forall a b. (a -> b) -> a -> b
    $ [Name] -> ConstructorVariant
    RecordConstructor [Name]
    fns)
                    where
                      gadtCase :: [Name]
    -> Type
    -> [Type]
    -> [FieldStrictness]
    -> (Name -> Q ConstructorVariant)
    -> Q [ConstructorInfo]
    gadtCase = Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> Type
    -> [TyVarBndrUnit]
    -> [Type]
    -> [Name]
    -> Type
    -> [Type]
    -> [FieldStrictness]
    -> (Name -> Q ConstructorVariant)
    -> Q [ConstructorInfo]
    normalizeGadtC Name
    typename [TyVarBndrUnit]
    params [Type]
    instTys Type
    resKind [TyVarBndrUnit]
    tyvars [Type]
    context
          in Con -> Q [ConstructorInfo]
    defaultCase

    normalizeStrictness :: Bang -> FieldStrictness
    normalizeStrictness :: Bang -> FieldStrictness
    normalizeStrictness (Bang SourceUnpackedness
    upk SourceStrictness
    str) =
      Unpackedness -> Strictness -> FieldStrictness
    FieldStrictness (SourceUnpackedness -> Unpackedness
    normalizeSourceUnpackedness SourceUnpackedness
    upk)
                      (SourceStrictness -> Strictness
    normalizeSourceStrictness SourceStrictness
    str)
      where
        normalizeSourceUnpackedness :: SourceUnpackedness -> Unpackedness
        normalizeSourceUnpackedness :: SourceUnpackedness -> Unpackedness
    normalizeSourceUnpackedness SourceUnpackedness
    NoSourceUnpackedness = Unpackedness
    UnspecifiedUnpackedness
        normalizeSourceUnpackedness SourceUnpackedness
    SourceNoUnpack       = Unpackedness
    NoUnpack
        normalizeSourceUnpackedness SourceUnpackedness
    SourceUnpack         = Unpackedness
    Unpack

        normalizeSourceStrictness :: SourceStrictness -> Strictness
        normalizeSourceStrictness :: SourceStrictness -> Strictness
    normalizeSourceStrictness SourceStrictness
    NoSourceStrictness = Strictness
    UnspecifiedStrictness
        normalizeSourceStrictness SourceStrictness
    SourceLazy         = Strictness
    Lazy
        normalizeSourceStrictness SourceStrictness
    SourceStrict       = Strictness
    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 :: Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> Type
    -> [TyVarBndrUnit]
    -> [Type]
    -> [Name]
    -> Type
    -> [Type]
    -> [FieldStrictness]
    -> (Name -> Q ConstructorVariant)
    -> Q [ConstructorInfo]
    normalizeGadtC Name
    typename [TyVarBndrUnit]
    params [Type]
    instTys Type
    resKind [TyVarBndrUnit]
    tyvars [Type]
    context [Name]
    names Type
    innerType
                   [Type]
    fields [FieldStrictness]
    stricts Name -> Q ConstructorVariant
    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 :: [TyVarBndrUnit]
    implicitTyvars = [Type] -> [TyVarBndrUnit]
    freeVariablesWellScoped
                              [[TyVarBndrSpec] -> [Type] -> [Type] -> Type -> Type
    curryType (Specificity -> [TyVarBndrUnit] -> [TyVarBndrSpec]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec [TyVarBndrUnit]
    tyvars)
                                         [Type]
    context [Type]
    fields Type
    innerType]
             allTyvars :: [TyVarBndrUnit]
    allTyvars = [TyVarBndrUnit]
    implicitTyvars [TyVarBndrUnit] -> [TyVarBndrUnit] -> [TyVarBndrUnit]
    forall a. [a] -> [a] -> [a]
    ++ [TyVarBndrUnit]
    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 :: [Name]
    conBoundNames =
               (TyVarBndrUnit -> [Name]) -> [TyVarBndrUnit] -> [Name]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (\TyVarBndrUnit
    tvb -> TyVarBndrUnit -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName TyVarBndrUnit
    tvbName -> [Name] -> [Name]
    forall a. a -> [a] -> [a]
    :Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables (TyVarBndrUnit -> Type
    forall flag. TyVarBndr_ flag -> Type
    tvKind TyVarBndrUnit
    tvb)) [TyVarBndrUnit]
    allTyvars
         conSubst <- Map Name (Q Name) -> Q (Map Name Name)
    forall (t :: * -> *) (m :: * -> *) a.
    (Traversable t, Monad m) =>
    t (m a) -> m (t a)
    forall (m :: * -> *) a. Monad m => Map Name (m a) -> m (Map Name a)
    T.sequence (Map Name (Q Name) -> Q (Map Name Name))
    -> Map Name (Q Name) -> Q (Map Name Name)
    forall a b. (a -> b) -> a -> b
    $ [(Name, Q Name)] -> Map Name (Q Name)
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [ (Name
    n, String -> Q Name
    forall (m :: * -> *). Quote m => String -> m Name
    newName (Name -> String
    nameBase Name
    n))
                                               | Name
    n <- [Name]
    conBoundNames ]
         let conSubst'     = (Name -> Type) -> Map Name Name -> Map Name Type
    forall a b. (a -> b) -> Map Name a -> Map Name b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Name -> Type
    VarT Map Name Name
    conSubst
             renamedTyvars =
               (TyVarBndrUnit -> TyVarBndrUnit)
    -> [TyVarBndrUnit] -> [TyVarBndrUnit]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Name -> TyVarBndrUnit)
    -> (Name -> Type -> TyVarBndrUnit)
    -> TyVarBndrUnit
    -> TyVarBndrUnit
    forall r flag.
    (Name -> r) -> (Name -> Type -> r) -> TyVarBndr_ flag -> r
    elimTV (\Name
    n   -> Name -> TyVarBndrUnit
    forall flag. DefaultBndrFlag flag => Name -> TyVarBndr flag
    plainTV  (Map Name Name
    conSubst Map Name Name -> Name -> Name
    forall k a. Ord k => Map k a -> k -> a
    Map.! Name
    n))
                           (\Name
    n Type
    k -> Name -> Type -> TyVarBndrUnit
    forall flag. DefaultBndrFlag flag => Name -> Type -> TyVarBndr flag
    kindedTV (Map Name Name
    conSubst Map Name Name -> Name -> Name
    forall k a. Ord k => Map k a -> k -> a
    Map.! Name
    n)
                                             (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    conSubst' Type
    k))) [TyVarBndrUnit]
    allTyvars
             renamedContext   = Map Name Type -> [Type] -> [Type]
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    conSubst' [Type]
    context
             renamedInnerType = Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    conSubst' Type
    innerType
             renamedFields    = Map Name Type -> [Type] -> [Type]
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    conSubst' [Type]
    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 Type
    t Type
    innerResKind -> (Type
    t, Type -> Maybe Type
    forall a. a -> Maybe a
    Just Type
    innerResKind, Type -> Maybe Type
    forall a. a -> Maybe a
    Just Type
    resKind)
                 Type
    _                   -> (Type
    innerType', Maybe Type
    forall a. Maybe a
    Nothing, Maybe Type
    forall a. Maybe a
    Nothing)

         case decomposeType innerType'' of
           ConT Name
    innerTyCon :| [Type]
    ts | Name
    typename Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    innerTyCon ->

             let -- See step (2) of Note [Tricky result kinds].
                 instTys' :: [Type]
    instTys' = Maybe Type -> [Type]
    forall a. Maybe a -> [a]
    maybeToList Maybe Type
    mbResKind [Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++ [Type]
    instTys
                 ts' :: [Type]
    ts' = Maybe Type -> [Type]
    forall a. Maybe a -> [a]
    maybeToList Maybe Type
    mbInnerResKind [Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++ [Type]
    ts

                 (Map Name Name
    substName, [Type]
    context1) =
                   Map Name Type
    -> Map Name Type
    -> (Map Name Name, [Type])
    -> (Map Name Name, [Type])
    closeOverKinds ([TyVarBndrUnit] -> Map Name Type
    forall flag. [TyVarBndr_ flag] -> Map Name Type
    kindsOfFVsOfTvbs [TyVarBndrUnit]
    renamedTyvars)
                                  ([TyVarBndrUnit] -> Map Name Type
    forall flag. [TyVarBndr_ flag] -> Map Name Type
    kindsOfFVsOfTvbs [TyVarBndrUnit]
    params)
                                  ([Type] -> [Type] -> (Map Name Name, [Type])
    mergeArguments [Type]
    instTys' [Type]
    ts')
                 subst :: Map Name Type
    subst    = Name -> Type
    VarT (Name -> Type) -> Map Name Name -> Map Name Type
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Map Name Name
    substName
                 exTyvars :: [TyVarBndrUnit]
    exTyvars = [ TyVarBndrUnit
    tv | TyVarBndrUnit
    tv <- [TyVarBndrUnit]
    renamedTyvars, Name -> Map Name Type -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    Map.notMember (TyVarBndrUnit -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName TyVarBndrUnit
    tv) Map Name Type
    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' :: [TyVarBndrUnit]
    exTyvars' = Map Name Type -> [TyVarBndrUnit] -> [TyVarBndrUnit]
    forall flag.
    Map Name Type -> [TyVarBndr_ flag] -> [TyVarBndr_ flag]
    substTyVarBndrKinds Map Name Type
    subst [TyVarBndrUnit]
    exTyvars
                 context2 :: [Type]
    context2  = Map Name Type -> [Type] -> [Type]
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution   Map Name Type
    subst ([Type]
    context1 [Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++ [Type]
    renamedContext)
                 fields' :: [Type]
    fields'   = Map Name Type -> [Type] -> [Type]
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution   Map Name Type
    subst [Type]
    renamedFields
             in [Q ConstructorInfo] -> Q [ConstructorInfo]
    forall (t :: * -> *) (m :: * -> *) a.
    (Traversable t, Monad m) =>
    t (m a) -> m (t a)
    forall (m :: * -> *) a. Monad m => [m a] -> m [a]
    sequence [ Name
    -> [TyVarBndrUnit]
    -> [Type]
    -> [Type]
    -> [FieldStrictness]
    -> ConstructorVariant
    -> ConstructorInfo
    ConstructorInfo Name
    name [TyVarBndrUnit]
    exTyvars' [Type]
    context2
                                           [Type]
    fields' [FieldStrictness]
    stricts (ConstructorVariant -> ConstructorInfo)
    -> Q ConstructorVariant -> Q ConstructorInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Q ConstructorVariant
    variantQ
                         | Name
    name <- [Name]
    names
                         , let variantQ :: Q ConstructorVariant
    variantQ = Name -> Q ConstructorVariant
    getVariant Name
    name
                         ]

           NonEmpty Type
    _ -> String -> Q [ConstructorInfo]
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "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 :: Map Name Type
    -> Map Name Type
    -> (Map Name Name, [Type])
    -> (Map Name Name, [Type])
    closeOverKinds Map Name Type
    domainFVKinds Map Name Type
    rangeFVKinds = (Map Name Name, [Type]) -> (Map Name Name, [Type])
    go
      where
        go :: (Map Name Name, Cxt) -> (Map Name Name, Cxt)
        go :: (Map Name Name, [Type]) -> (Map Name Name, [Type])
    go (Map Name Name
    subst, [Type]
    context) =
          let substList :: [(Name, Name)]
    substList = Map Name Name -> [(Name, Name)]
    forall k a. Map k a -> [(k, a)]
    Map.toList Map Name Name
    subst
              ([Type]
    kindsInner, [Type]
    kindsOuter) =
                [(Type, Type)] -> ([Type], [Type])
    forall a b. [(a, b)] -> ([a], [b])
    unzip ([(Type, Type)] -> ([Type], [Type]))
    -> [(Type, Type)] -> ([Type], [Type])
    forall a b. (a -> b) -> a -> b
    $
                ((Name, Name) -> Maybe (Type, Type))
    -> [(Name, Name)] -> [(Type, Type)]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe (\(Name
    d, Name
    r) -> do d' <- Name -> Map Name Type -> Maybe Type
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup Name
    d Map Name Type
    domainFVKinds
                                        r' <- Map.lookup r rangeFVKinds
                                        return (d', r'))
                         [(Name, Name)]
    substList
              (Map Name Name
    kindSubst, [Type]
    kindContext) = [Type] -> [Type] -> (Map Name Name, [Type])
    mergeArguments [Type]
    kindsOuter [Type]
    kindsInner
              (Map Name Name
    restSubst, [Type]
    restContext)
                = if Map Name Name -> Bool
    forall k a. Map k a -> Bool
    Map.null Map Name Name
    kindSubst -- Fixed-point calculation
                     then (Map Name Name
    forall k a. Map k a
    Map.empty, [])
                     else (Map Name Name, [Type]) -> (Map Name Name, [Type])
    go (Map Name Name
    kindSubst, [Type]
    kindContext)
              finalSubst :: Map Name Name
    finalSubst   = [Map Name Name] -> Map Name Name
    forall (f :: * -> *) k a.
    (Foldable f, Ord k) =>
    f (Map k a) -> Map k a
    Map.unions [Map Name Name
    subst, Map Name Name
    kindSubst, Map Name Name
    restSubst]
              finalContext :: [Type]
    finalContext = [Type] -> [Type]
    forall a. Eq a => [a] -> [a]
    nub ([Type] -> [Type]) -> [Type] -> [Type]
    forall a b. (a -> b) -> a -> b
    $ [[Type]] -> [Type]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [[Type]
    context, [Type]
    kindContext, [Type]
    restContext]
                -- Use `nub` here in an effort to minimize the number of
                -- redundant equality constraints in the returned context.
          in (Map Name Name
    finalSubst, [Type]
    finalContext)

    -- Look into a list of types and map each free variable name to its kind.
    kindsOfFVsOfTypes :: [Type] -> Map Name Kind
    kindsOfFVsOfTypes :: [Type] -> Map Name Type
    kindsOfFVsOfTypes = (Type -> Map Name Type) -> [Type] -> Map Name Type
    forall m a. Monoid m => (a -> m) -> [a] -> m
    forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap Type -> Map Name Type
    go
      where
        go :: Type -> Map Name Kind
        go :: Type -> Map Name Type
    go (AppT Type
    t1 Type
    t2) = Type -> Map Name Type
    go Type
    t1 Map Name Type -> Map Name Type -> Map Name Type
    forall k a. Ord k => Map k a -> Map k a -> Map k a
    `Map.union` Type -> Map Name Type
    go Type
    t2
        go (SigT Type
    t Type
    k) =
          let kSigs :: Map Name Type
    kSigs = Type -> Map Name Type
    go Type
    k
          in case Type
    t of
               VarT Name
    n -> Name -> Type -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert Name
    n Type
    k Map Name Type
    kSigs
               Type
    _      -> Type -> Map Name Type
    go Type
    t Map Name Type -> Map Name Type -> Map Name Type
    forall k a. Ord k => Map k a -> Map k a -> Map k a
    `Map.union` Map Name Type
    kSigs

        go (ForallT {})    = Map Name Type
    forall a. a
    forallError
    #if MIN_VERSION_template_haskell(2,16,0)
        go (ForallVisT {}) = Map Name Type
    forall a. a
    forallError
    #endif

        go Type
    _ = Map Name Type
    forall k a. Map k a
    Map.empty

        forallError :: a
        forallError :: forall a. a
    forallError = String -> a
    forall a. HasCallStack => String -> a
    error String
    "`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 :: forall flag. [TyVarBndr_ flag] -> Map Name Type
    kindsOfFVsOfTvbs = (TyVarBndr_ flag -> Map Name Type)
    -> [TyVarBndr_ flag] -> Map Name Type
    forall m a. Monoid m => (a -> m) -> [a] -> m
    forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap TyVarBndr_ flag -> Map Name Type
    forall flag. TyVarBndr_ flag -> Map Name Type
    go
      where
        go :: TyVarBndr_ flag -> Map Name Kind
        go :: forall flag. TyVarBndr_ flag -> Map Name Type
    go = (Name -> Map Name Type)
    -> (Name -> Type -> Map Name Type)
    -> TyVarBndr_ flag
    -> Map Name Type
    forall r flag.
    (Name -> r) -> (Name -> Type -> r) -> TyVarBndr_ flag -> r
    elimTV (\Name
    n -> Name -> Type -> Map Name Type
    forall k a. k -> a -> Map k a
    Map.singleton Name
    n Type
    starK)
                    (\Name
    n Type
    k -> let kSigs :: Map Name Type
    kSigs = [Type] -> Map Name Type
    kindsOfFVsOfTypes [Type
    k]
                             in Name -> Type -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert Name
    n Type
    k Map Name Type
    kSigs)

    mergeArguments ::
      [Type] {- ^ outer parameters                    -} ->
      [Type] {- ^ inner parameters (specializations ) -} ->
      (Map Name Name, Cxt)
    mergeArguments :: [Type] -> [Type] -> (Map Name Name, [Type])
    mergeArguments [Type]
    ns [Type]
    ts = ((Type, Type)
     -> (Map Name Name, [Type]) -> (Map Name Name, [Type]))
    -> (Map Name Name, [Type])
    -> [(Type, Type)]
    -> (Map Name Name, [Type])
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (Type, Type) -> (Map Name Name, [Type]) -> (Map Name Name, [Type])
    aux (Map Name Name
    forall k a. Map k a
    Map.empty, []) ([Type] -> [Type] -> [(Type, Type)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Type]
    ns [Type]
    ts)
      where

        aux :: (Type, Type) -> (Map Name Name, [Type]) -> (Map Name Name, [Type])
    aux (Type
    f `AppT` Type
    x, Type
    g `AppT` Type
    y) (Map Name Name, [Type])
    sc =
          (Type, Type) -> (Map Name Name, [Type]) -> (Map Name Name, [Type])
    aux (Type
    x,Type
    y) ((Type, Type) -> (Map Name Name, [Type]) -> (Map Name Name, [Type])
    aux (Type
    f,Type
    g) (Map Name Name, [Type])
    sc)

        aux (VarT Name
    n,Type
    p) (Map Name Name
    subst, [Type]
    context) =
          case Type
    p of
            VarT Name
    m | Name
    m Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    n  -> (Map Name Name
    subst, [Type]
    context)
                       -- If the two variables are the same, don't bother extending
                       -- the substitution. (This is purely an optimization.)
                   | Just Name
    n' <- Name -> Map Name Name -> Maybe Name
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup Name
    m Map Name Name
    subst
                   , Name
    n Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    n' -> (Map Name Name
    subst, [Type]
    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.)
                   | Name -> Map Name Name -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    Map.notMember Name
    m Map Name Name
    subst -> (Name -> Name -> Map Name Name -> Map Name Name
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert Name
    m Name
    n Map Name Name
    subst, [Type]
    context)
            Type
    _ -> (Map Name Name
    subst, Type -> Type -> Type
    equalPred (Name -> Type
    VarT Name
    n) Type
    p Type -> [Type] -> [Type]
    forall a. a -> [a] -> [a]
    : [Type]
    context)

        aux (SigT Type
    x Type
    _, Type
    y) (Map Name Name, [Type])
    sc = (Type, Type) -> (Map Name Name, [Type]) -> (Map Name Name, [Type])
    aux (Type
    x,Type
    y) (Map Name Name, [Type])
    sc -- learn about kinds??
        -- This matches *after* VarT so that we can compute a substitution
        -- that includes the kind signature.
        aux (Type
    x, SigT Type
    y Type
    _) (Map Name Name, [Type])
    sc = (Type, Type) -> (Map Name Name, [Type]) -> (Map Name Name, [Type])
    aux (Type
    x,Type
    y) (Map Name Name, [Type])
    sc

        aux (Type, Type)
    _ (Map Name Name, [Type])
    sc = (Map Name Name, [Type])
    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 :: Type -> Q Type
    resolveTypeSynonyms Type
    t =
      let (Type
    f, [TypeArg]
    xs) = Type -> (Type, [TypeArg])
    decomposeTypeArgs Type
    t
          normal_xs :: [Type]
    normal_xs = [TypeArg] -> [Type]
    filterTANormals [TypeArg]
    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 :: Type -> Q Type
    defaultCase Type
    ty = (Type -> TypeArg -> Type) -> Type -> [TypeArg] -> Type
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Type -> TypeArg -> Type
    appTypeArg Type
    ty ([TypeArg] -> Type) -> Q [TypeArg] -> Q Type
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (TypeArg -> Q TypeArg) -> [TypeArg] -> Q [TypeArg]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM TypeArg -> Q TypeArg
    resolveTypeArgSynonyms [TypeArg]
    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 :: Name -> Type -> Q Type
    expandCon Name
    n Type
    ty = do
            mbInfo <- Name -> Q (Maybe Info)
    reifyMaybe Name
    n
            case mbInfo of
              Just (TyConI (TySynD Name
    _ [TyVarBndr BndrVis]
    synvars Type
    def))
                |  [Type] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Type]
    normal_xs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [TyVarBndr BndrVis] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [TyVarBndr BndrVis]
    synvars -- Don't expand undersaturated type synonyms (#88)
                -> Type -> Q Type
    resolveTypeSynonyms (Type -> Q Type) -> Type -> Q Type
    forall a b. (a -> b) -> a -> b
    $ [TyVarBndr BndrVis] -> [Type] -> Type -> Type
    forall flag. [TyVarBndr_ flag] -> [Type] -> Type -> Type
    expandSynonymRHS [TyVarBndr BndrVis]
    synvars [Type]
    normal_xs Type
    def
              Maybe Info
    _ -> Type -> Q Type
    defaultCase Type
    ty

      in case Type
    f of
           ForallT [TyVarBndrSpec]
    tvbs [Type]
    ctxt Type
    body ->
             [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT ([TyVarBndrSpec] -> [Type] -> Type -> Type)
    -> Q [TyVarBndrSpec] -> Q ([Type] -> Type -> Type)
    forall a b. (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` (TyVarBndrSpec -> Q TyVarBndrSpec)
    -> [TyVarBndrSpec] -> Q [TyVarBndrSpec]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM TyVarBndrSpec -> Q TyVarBndrSpec
    forall flag. TyVarBndr_ flag -> Q (TyVarBndr_ flag)
    resolve_tvb_syns [TyVarBndrSpec]
    tvbs
                       Q ([Type] -> Type -> Type) -> Q [Type] -> Q (Type -> Type)
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    `ap` (Type -> Q Type) -> [Type] -> Q [Type]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Type -> Q Type
    resolvePredSynonyms [Type]
    ctxt
                       Q (Type -> Type) -> Q Type -> Q Type
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    `ap` Type -> Q Type
    resolveTypeSynonyms Type
    body
           SigT Type
    ty Type
    ki -> do
             ty' <- Type -> Q Type
    resolveTypeSynonyms Type
    ty
             ki' <- resolveKindSynonyms ki
             defaultCase $ SigT ty' ki'
           ConT Name
    n -> Name -> Type -> Q Type
    expandCon Name
    n Type
    f
           InfixT Type
    t1 Name
    n Type
    t2 -> do
             t1' <- Type -> Q Type
    resolveTypeSynonyms Type
    t1
             t2' <- resolveTypeSynonyms t2
             expandCon n (InfixT t1' n t2')
           UInfixT Type
    t1 Name
    n Type
    t2 -> do
             t1' <- Type -> Q Type
    resolveTypeSynonyms Type
    t1
             t2' <- resolveTypeSynonyms t2
             expandCon n (UInfixT t1' n t2')
    #if MIN_VERSION_template_haskell(2,15,0)
           ImplicitParamT String
    n Type
    t -> do
             String -> Type -> Type
    ImplicitParamT String
    n (Type -> Type) -> Q Type -> Q Type
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Q Type
    resolveTypeSynonyms Type
    t
    #endif
    #if MIN_VERSION_template_haskell(2,16,0)
           ForallVisT [TyVarBndrUnit]
    tvbs Type
    body ->
             [TyVarBndrUnit] -> Type -> Type
    ForallVisT ([TyVarBndrUnit] -> Type -> Type)
    -> Q [TyVarBndrUnit] -> Q (Type -> Type)
    forall a b. (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` (TyVarBndrUnit -> Q TyVarBndrUnit)
    -> [TyVarBndrUnit] -> Q [TyVarBndrUnit]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM TyVarBndrUnit -> Q TyVarBndrUnit
    forall flag. TyVarBndr_ flag -> Q (TyVarBndr_ flag)
    resolve_tvb_syns [TyVarBndrUnit]
    tvbs
                          Q (Type -> Type) -> Q Type -> Q Type
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    `ap` Type -> Q Type
    resolveTypeSynonyms Type
    body
    #endif
    #if MIN_VERSION_template_haskell(2,19,0)
           PromotedInfixT Type
    t1 Name
    n Type
    t2 -> do
             t1' <- Type -> Q Type
    resolveTypeSynonyms Type
    t1
             t2' <- resolveTypeSynonyms t2
             return $ PromotedInfixT t1' n t2'
           PromotedUInfixT Type
    t1 Name
    n Type
    t2 -> do
             t1' <- Type -> Q Type
    resolveTypeSynonyms Type
    t1
             t2' <- resolveTypeSynonyms t2
             return $ PromotedUInfixT t1' n t2'
    #endif
           Type
    _ -> Type -> Q Type
    defaultCase Type
    f

    -- | Expand all of the type synonyms in a 'TypeArg'.
    resolveTypeArgSynonyms :: TypeArg -> Q TypeArg
    resolveTypeArgSynonyms :: TypeArg -> Q TypeArg
    resolveTypeArgSynonyms (TANormal Type
    t) = Type -> TypeArg
    TANormal (Type -> TypeArg) -> Q Type -> Q TypeArg
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Q Type
    resolveTypeSynonyms Type
    t
    resolveTypeArgSynonyms (TyArg Type
    k)    = Type -> TypeArg
    TyArg    (Type -> TypeArg) -> Q Type -> Q TypeArg
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Q Type
    resolveKindSynonyms Type
    k

    -- | Expand all of the type synonyms in a 'Kind'.
    resolveKindSynonyms :: Kind -> Q Kind
    resolveKindSynonyms :: Type -> Q Type
    resolveKindSynonyms = Type -> Q Type
    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 :: forall flag. TyVarBndr_ flag -> Q (TyVarBndr_ flag)
    resolve_tvb_syns = (Type -> Q Type) -> TyVarBndr_ flag -> Q (TyVarBndr_ flag)
    forall (m :: * -> *) flag.
    Monad m =>
    (Type -> m Type) -> TyVarBndr_ flag -> m (TyVarBndr_ flag)
    mapMTVKind Type -> Q Type
    resolveKindSynonyms

    expandSynonymRHS ::
      [TyVarBndr_ flag] {- ^ Substitute these variables... -} ->
      [Type]            {- ^ ...with these types... -} ->
      Type              {- ^ ...inside of this type. -} ->
      Type
    expandSynonymRHS :: forall flag. [TyVarBndr_ flag] -> [Type] -> Type -> Type
    expandSynonymRHS [TyVarBndr_ flag]
    synvars [Type]
    ts Type
    def =
      let argNames :: [Name]
    argNames    = (TyVarBndr_ flag -> Name) -> [TyVarBndr_ flag] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr_ flag -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName [TyVarBndr_ flag]
    synvars
          ([Type]
    args,[Type]
    rest) = Int -> [Type] -> ([Type], [Type])
    forall a. Int -> [a] -> ([a], [a])
    splitAt ([Name] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Name]
    argNames) [Type]
    ts
          subst :: Map Name Type
    subst       = [(Name, Type)] -> Map Name Type
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList ([Name] -> [Type] -> [(Name, Type)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Name]
    argNames [Type]
    args)
      in (Type -> Type -> Type) -> Type -> [Type] -> Type
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Type -> Type -> Type
    AppT (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst Type
    def) [Type]
    rest

    -- | Expand all of the type synonyms in a 'Pred'.
    resolvePredSynonyms :: Pred -> Q Pred
    resolvePredSynonyms :: Type -> Q Type
    resolvePredSynonyms = Type -> Q Type
    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 :: Type -> NonEmpty Type
    decomposeType Type
    t =
      case Type -> (Type, [TypeArg])
    decomposeTypeArgs Type
    t of
        (Type
    f, [TypeArg]
    x) -> Type
    f Type -> [Type] -> NonEmpty Type
    forall a. a -> [a] -> NonEmpty a
    :| [TypeArg] -> [Type]
    filterTANormals [TypeArg]
    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 :: Type -> (Type, [TypeArg])
    decomposeTypeArgs = [TypeArg] -> Type -> (Type, [TypeArg])
    go []
      where
        go :: [TypeArg] -> Type -> (Type, [TypeArg])
        go :: [TypeArg] -> Type -> (Type, [TypeArg])
    go [TypeArg]
    args (AppT Type
    f Type
    x)     = [TypeArg] -> Type -> (Type, [TypeArg])
    go (Type -> TypeArg
    TANormal Type
    xTypeArg -> [TypeArg] -> [TypeArg]
    forall a. a -> [a] -> [a]
    :[TypeArg]
    args) Type
    f
        go [TypeArg]
    args (ParensT Type
    t)    = [TypeArg] -> Type -> (Type, [TypeArg])
    go [TypeArg]
    args Type
    t
    #if MIN_VERSION_template_haskell(2,15,0)
        go [TypeArg]
    args (AppKindT Type
    f Type
    x) = [TypeArg] -> Type -> (Type, [TypeArg])
    go (Type -> TypeArg
    TyArg Type
    xTypeArg -> [TypeArg] -> [TypeArg]
    forall a. a -> [a] -> [a]
    :[TypeArg]
    args) Type
    f
    #endif
        go [TypeArg]
    args Type
    t              = (Type
    t, [TypeArg]
    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 :: Type -> TypeArg -> Type
    appTypeArg Type
    f (TANormal Type
    x) = Type
    f Type -> Type -> Type
    `AppT` Type
    x
    appTypeArg Type
    f (TyArg Type
    _k) =
    #if MIN_VERSION_template_haskell(2,15,0)
      Type
    f Type -> Type -> Type
    `AppKindT` Type
    _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 :: [TypeArg] -> [Type]
    filterTANormals = (TypeArg -> Maybe Type) -> [TypeArg] -> [Type]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe TypeArg -> Maybe Type
    f
      where
        f :: TypeArg -> Maybe Type
        f :: TypeArg -> Maybe Type
    f (TANormal Type
    t) = Type -> Maybe Type
    forall a. a -> Maybe a
    Just Type
    t
        f (TyArg {})   = Maybe Type
    forall a. Maybe a
    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 :: Type -> ([TyVarBndrSpec], [Type], NonEmptySnoc Type)
    uncurryType = [TyVarBndrSpec]
    -> [Type]
    -> [Type]
    -> Type
    -> ([TyVarBndrSpec], [Type], NonEmptySnoc Type)
    go [] [] []
      where
        go :: [TyVarBndrSpec]
    -> [Type]
    -> [Type]
    -> Type
    -> ([TyVarBndrSpec], [Type], NonEmptySnoc Type)
    go [TyVarBndrSpec]
    tvbs [Type]
    ctxt [Type]
    args (AppT (AppT Type
    ArrowT Type
    t1) Type
    t2) = [TyVarBndrSpec]
    -> [Type]
    -> [Type]
    -> Type
    -> ([TyVarBndrSpec], [Type], NonEmptySnoc Type)
    go [TyVarBndrSpec]
    tvbs [Type]
    ctxt (Type
    t1Type -> [Type] -> [Type]
    forall a. a -> [a] -> [a]
    :[Type]
    args) Type
    t2
        go [TyVarBndrSpec]
    tvbs [Type]
    ctxt [Type]
    args (ForallT [TyVarBndrSpec]
    tvbs' [Type]
    ctxt' Type
    t)    = [TyVarBndrSpec]
    -> [Type]
    -> [Type]
    -> Type
    -> ([TyVarBndrSpec], [Type], NonEmptySnoc Type)
    go ([TyVarBndrSpec]
    tvbs[TyVarBndrSpec] -> [TyVarBndrSpec] -> [TyVarBndrSpec]
    forall a. [a] -> [a] -> [a]
    ++[TyVarBndrSpec]
    tvbs') ([Type]
    ctxt[Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++[Type]
    ctxt') [Type]
    args Type
    t
        go [TyVarBndrSpec]
    tvbs [Type]
    ctxt [Type]
    args Type
    t                          = ([TyVarBndrSpec]
    tvbs, [Type]
    ctxt, [Type] -> [Type]
    forall a. [a] -> [a]
    reverse [Type]
    args [Type] -> Type -> NonEmptySnoc Type
    forall a. [a] -> a -> NonEmptySnoc a
    :|- Type
    t)

    -- Reconstruct a function type from its type variable binders, context,
    -- argument types and return type.
    curryType :: [TyVarBndrSpec] -> Cxt -> [Type] -> Type -> Type
    curryType :: [TyVarBndrSpec] -> [Type] -> [Type] -> Type -> Type
    curryType [TyVarBndrSpec]
    tvbs [Type]
    ctxt [Type]
    args Type
    res =
      [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT [TyVarBndrSpec]
    tvbs [Type]
    ctxt (Type -> Type) -> Type -> Type
    forall a b. (a -> b) -> a -> b
    $ (Type -> Type -> Type) -> Type -> [Type] -> Type
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\Type
    arg Type
    t -> Type
    ArrowT Type -> Type -> Type
    `AppT` Type
    arg Type -> Type -> Type
    `AppT` Type
    t) Type
    res [Type]
    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 :: Type -> (FunArgs, Type)
    unravelType (ForallT [TyVarBndrSpec]
    tvbs [Type]
    cxt Type
    ty) =
      let (FunArgs
    args, Type
    res) = Type -> (FunArgs, Type)
    unravelType Type
    ty in
      (ForallTelescope -> FunArgs -> FunArgs
    FAForalls ([TyVarBndrSpec] -> ForallTelescope
    ForallInvis [TyVarBndrSpec]
    tvbs) ([Type] -> FunArgs -> FunArgs
    FACxt [Type]
    cxt FunArgs
    args), Type
    res)
    unravelType (AppT (AppT Type
    ArrowT Type
    t1) Type
    t2) =
      let (FunArgs
    args, Type
    res) = Type -> (FunArgs, Type)
    unravelType Type
    t2 in
      (Type -> FunArgs -> FunArgs
    FAAnon Type
    t1 FunArgs
    args, Type
    res)
    #if __GLASGOW_HASKELL__ >= 809
    unravelType (ForallVisT [TyVarBndrUnit]
    tvbs Type
    ty) =
      let (FunArgs
    args, Type
    res) = Type -> (FunArgs, Type)
    unravelType Type
    ty in
      (ForallTelescope -> FunArgs -> FunArgs
    FAForalls ([TyVarBndrUnit] -> ForallTelescope
    ForallVis [TyVarBndrUnit]
    tvbs) FunArgs
    args, Type
    res)
    #endif
    unravelType Type
    t = (FunArgs
    FANil, Type
    t)

    -- | Reconstruct an arrow 'Type' from its argument and result types.
    ravelType :: FunArgs -> Type -> Type
    ravelType :: FunArgs -> Type -> Type
    ravelType FunArgs
    FANil Type
    res = Type
    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 [TyVarBndrSpec]
    tvbs) (FACxt [Type]
    p FunArgs
    args)) Type
    res =
      [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT [TyVarBndrSpec]
    tvbs [Type]
    p (FunArgs -> Type -> Type
    ravelType FunArgs
    args Type
    res)
    ravelType (FAForalls (ForallInvis  [TyVarBndrSpec]
    tvbs)  FunArgs
    args)  Type
    res = [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT [TyVarBndrSpec]
    tvbs [] (FunArgs -> Type -> Type
    ravelType FunArgs
    args Type
    res)
    ravelType (FAForalls (ForallVis   [TyVarBndrUnit]
    _tvbs) FunArgs
    _args) Type
    _res =
    #if __GLASGOW_HASKELL__ >= 809
          [TyVarBndrUnit] -> Type -> Type
    ForallVisT [TyVarBndrUnit]
    _tvbs (FunArgs -> Type -> Type
    ravelType FunArgs
    _args Type
    _res)
    #else
          error "Visible dependent quantification supported only on GHC 8.10+"
    #endif
    ravelType (FACxt [Type]
    cxt FunArgs
    args) Type
    res = [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT [] [Type]
    cxt (FunArgs -> Type -> Type
    ravelType FunArgs
    args Type
    res)
    ravelType (FAAnon Type
    t FunArgs
    args)  Type
    res = Type -> Type -> Type
    AppT (Type -> Type -> Type
    AppT Type
    ArrowT Type
    t) (FunArgs -> Type -> Type
    ravelType FunArgs
    args Type
    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 :: FunArgs -> [Type]
    funArgTys FunArgs
    FANil = []
    funArgTys (FAForalls ForallTelescope
    tele FunArgs
    args) =
      ForallTelescope -> [Type]
    forallTelescopeTys ForallTelescope
    tele [Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++ FunArgs -> [Type]
    funArgTys FunArgs
    args
    funArgTys (FACxt [Type]
    ctxt FunArgs
    args) =
      [Type]
    ctxt [Type] -> [Type] -> [Type]
    forall a. [a] -> [a] -> [a]
    ++ FunArgs -> [Type]
    funArgTys FunArgs
    args
    funArgTys (FAAnon Type
    anon FunArgs
    args) =
      Type
    anon Type -> [Type] -> [Type]
    forall a. a -> [a] -> [a]
    : FunArgs -> [Type]
    funArgTys FunArgs
    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 :: ForallTelescope -> [Type]
    forallTelescopeTys (ForallVis [TyVarBndrUnit]
    tvbs)   = [TyVarBndrUnit] -> [Type]
    forall flag. [TyVarBndr_ flag] -> [Type]
    bndrParams [TyVarBndrUnit]
    tvbs
    forallTelescopeTys (ForallInvis [TyVarBndrSpec]
    tvbs) = [TyVarBndrSpec] -> [Type]
    forall flag. [TyVarBndr_ flag] -> [Type]
    bndrParams [TyVarBndrSpec]
    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 :: forall a. [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    filterVisFunArgsUpTo = [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_fun_args
      where
        go_fun_args :: [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
        go_fun_args :: [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_fun_args [] FunArgs
    args =
          ([], FunArgs
    args)
        go_fun_args (a
    _:[a]
    _) FunArgs
    FANil =
          String -> ([(a, VisFunArg)], FunArgs)
    forall a. HasCallStack => String -> a
    error String
    "filterVisFunArgsUpTo.go_fun_args: Too few FunArgs"
        go_fun_args [a]
    xs (FACxt [Type]
    _ FunArgs
    args) =
          [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_fun_args [a]
    xs FunArgs
    args
        go_fun_args (a
    x:[a]
    xs) (FAAnon Type
    t FunArgs
    args) =
          let ([(a, VisFunArg)]
    xs', FunArgs
    args') = [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_fun_args [a]
    xs FunArgs
    args in
          ((a
    x, Type -> VisFunArg
    VisFAAnon Type
    t)(a, VisFunArg) -> [(a, VisFunArg)] -> [(a, VisFunArg)]
    forall a. a -> [a] -> [a]
    :[(a, VisFunArg)]
    xs', FunArgs
    args')
        go_fun_args [a]
    xs (FAForalls ForallTelescope
    tele FunArgs
    args) =
          case ForallTelescope
    tele of
            ForallVis [TyVarBndrUnit]
    tvbs ->
              [TyVarBndrUnit] -> [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_vis_tvbs [TyVarBndrUnit]
    tvbs [a]
    xs FunArgs
    args
            ForallInvis [TyVarBndrSpec]
    _ ->
              [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_fun_args [a]
    xs FunArgs
    args

        go_vis_tvbs :: [TyVarBndrUnit] -> [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
        go_vis_tvbs :: [TyVarBndrUnit] -> [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_vis_tvbs [] [a]
    xs FunArgs
    args =
          [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_fun_args [a]
    xs FunArgs
    args
        go_vis_tvbs (TyVarBndrUnit
    tvb:[TyVarBndrUnit]
    tvbs) (a
    x:[a]
    xs) FunArgs
    args =
          let ([(a, VisFunArg)]
    xs', FunArgs
    args') = [TyVarBndrUnit] -> [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    go_vis_tvbs [TyVarBndrUnit]
    tvbs [a]
    xs FunArgs
    args in
          ((a
    x, TyVarBndrUnit -> VisFunArg
    VisFADep TyVarBndrUnit
    tvb)(a, VisFunArg) -> [(a, VisFunArg)] -> [(a, VisFunArg)]
    forall a. a -> [a] -> [a]
    :[(a, VisFunArg)]
    xs', FunArgs
    args')
        go_vis_tvbs [TyVarBndrUnit]
    tvbs [] FunArgs
    args =
          ([], ForallTelescope -> FunArgs -> FunArgs
    FAForalls ([TyVarBndrUnit] -> ForallTelescope
    ForallVis [TyVarBndrUnit]
    tvbs) FunArgs
    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 :: forall a. [a] -> Type -> ([(a, VisFunArg)], Type)
    unravelKindUpTo [a]
    xs Type
    k = ([(a, VisFunArg)]
    xs', FunArgs -> Type -> Type
    ravelType FunArgs
    args' Type
    res)
      where
        (FunArgs
    args, Type
    res) = Type -> (FunArgs, Type)
    unravelType Type
    k
        ([(a, VisFunArg)]
    xs', FunArgs
    args') = [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    forall a. [a] -> FunArgs -> ([(a, VisFunArg)], FunArgs)
    filterVisFunArgsUpTo [a]
    xs FunArgs
    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 :: Type -> Q Type
    resolveInfixT (ForallT [TyVarBndrSpec]
    vs [Type]
    cx Type
    t) = [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT ([TyVarBndrSpec] -> [Type] -> Type -> Type)
    -> Q [TyVarBndrSpec] -> Q ([Type] -> Type -> Type)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (TyVarBndrSpec -> Q TyVarBndrSpec)
    -> [TyVarBndrSpec] -> Q [TyVarBndrSpec]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [b]
    traverse ((Type -> Q Type) -> TyVarBndrSpec -> Q TyVarBndrSpec
    forall (f :: * -> *) flag.
    Applicative f =>
    (Type -> f Type) -> TyVarBndr_ flag -> f (TyVarBndr_ flag)
    traverseTVKind Type -> Q Type
    resolveInfixT) [TyVarBndrSpec]
    vs
                                              Q ([Type] -> Type -> Type) -> Q [Type] -> Q (Type -> Type)
    forall a b. Q (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> (Type -> Q Type) -> [Type] -> Q [Type]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Type -> Q Type
    resolveInfixT [Type]
    cx
                                              Q (Type -> Type) -> Q Type -> Q Type
    forall a b. Q (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Type -> Q Type
    resolveInfixT Type
    t
    resolveInfixT (Type
    f `AppT` Type
    x)      = Type -> Q Type
    resolveInfixT Type
    f Q Type -> Q Type -> Q Type
    forall (m :: * -> *). Quote m => m Type -> m Type -> m Type
    `appT` Type -> Q Type
    resolveInfixT Type
    x
    resolveInfixT (ParensT Type
    t)       = Type -> Q Type
    resolveInfixT Type
    t
    resolveInfixT (InfixT Type
    l Name
    o Type
    r)    = Name -> Q Type
    forall (m :: * -> *). Quote m => Name -> m Type
    conT Name
    o Q Type -> Q Type -> Q Type
    forall (m :: * -> *). Quote m => m Type -> m Type -> m Type
    `appT` Type -> Q Type
    resolveInfixT Type
    l Q Type -> Q Type -> Q Type
    forall (m :: * -> *). Quote m => m Type -> m Type -> m Type
    `appT` Type -> Q Type
    resolveInfixT Type
    r
    resolveInfixT (SigT Type
    t Type
    k)        = Type -> Type -> Type
    SigT (Type -> Type -> Type) -> Q Type -> Q (Type -> Type)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Q Type
    resolveInfixT Type
    t Q (Type -> Type) -> Q Type -> Q Type
    forall a b. Q (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Type -> Q Type
    resolveInfixT Type
    k
    resolveInfixT t :: Type
    t@UInfixT{}       = Type -> Q Type
    resolveInfixT (Type -> Q Type) -> Q Type -> Q Type
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< InfixList -> Q Type
    resolveInfixT1 (Type -> InfixList
    gatherUInfixT Type
    t)
    #if MIN_VERSION_template_haskell(2,15,0)
    resolveInfixT (Type
    f `AppKindT` Type
    x)  = Q Type -> Q Type -> Q Type
    forall (m :: * -> *). Quote m => m Type -> m Type -> m Type
    appKindT (Type -> Q Type
    resolveInfixT Type
    f) (Type -> Q Type
    resolveInfixT Type
    x)
    resolveInfixT (ImplicitParamT String
    n Type
    t)
                                    = String -> Q Type -> Q Type
    forall (m :: * -> *). Quote m => String -> m Type -> m Type
    implicitParamT String
    n (Q Type -> Q Type) -> Q Type -> Q Type
    forall a b. (a -> b) -> a -> b
    $ Type -> Q Type
    resolveInfixT Type
    t
    #endif
    #if MIN_VERSION_template_haskell(2,16,0)
    resolveInfixT (ForallVisT [TyVarBndrUnit]
    vs Type
    t) = [TyVarBndrUnit] -> Type -> Type
    ForallVisT ([TyVarBndrUnit] -> Type -> Type)
    -> Q [TyVarBndrUnit] -> Q (Type -> Type)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (TyVarBndrUnit -> Q TyVarBndrUnit)
    -> [TyVarBndrUnit] -> Q [TyVarBndrUnit]
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [b]
    traverse ((Type -> Q Type) -> TyVarBndrUnit -> Q TyVarBndrUnit
    forall (f :: * -> *) flag.
    Applicative f =>
    (Type -> f Type) -> TyVarBndr_ flag -> f (TyVarBndr_ flag)
    traverseTVKind Type -> Q Type
    resolveInfixT) [TyVarBndrUnit]
    vs
                                                 Q (Type -> Type) -> Q Type -> Q Type
    forall a b. Q (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Type -> Q Type
    resolveInfixT Type
    t
    #endif
    #if MIN_VERSION_template_haskell(2,19,0)
    resolveInfixT (PromotedInfixT Type
    l Name
    o Type
    r)
                                    = Name -> Q Type
    forall (m :: * -> *). Quote m => Name -> m Type
    promotedT Name
    o Q Type -> Q Type -> Q Type
    forall (m :: * -> *). Quote m => m Type -> m Type -> m Type
    `appT` Type -> Q Type
    resolveInfixT Type
    l Q Type -> Q Type -> Q Type
    forall (m :: * -> *). Quote m => m Type -> m Type -> m Type
    `appT` Type -> Q Type
    resolveInfixT Type
    r
    resolveInfixT t :: Type
    t@PromotedUInfixT{}
                                    = Type -> Q Type
    resolveInfixT (Type -> Q Type) -> Q Type -> Q Type
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< InfixList -> Q Type
    resolveInfixT1 (Type -> InfixList
    gatherUInfixT Type
    t)
    #endif
    resolveInfixT Type
    t                 = Type -> Q Type
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Type
    t

    gatherUInfixT :: Type -> InfixList
    gatherUInfixT :: Type -> InfixList
    gatherUInfixT (UInfixT Type
    l Name
    o Type
    r)         = InfixList -> Name -> Bool -> InfixList -> InfixList
    ilAppend (Type -> InfixList
    gatherUInfixT Type
    l) Name
    o Bool
    False (Type -> InfixList
    gatherUInfixT Type
    r)
    #if MIN_VERSION_template_haskell(2,19,0)
    gatherUInfixT (PromotedUInfixT Type
    l Name
    o Type
    r) = InfixList -> Name -> Bool -> InfixList -> InfixList
    ilAppend (Type -> InfixList
    gatherUInfixT Type
    l) Name
    o Bool
    True  (Type -> InfixList
    gatherUInfixT Type
    r)
    #endif
    gatherUInfixT Type
    t = Type -> InfixList
    ILNil Type
    t

    -- This can fail due to incompatible fixities
    resolveInfixT1 :: InfixList -> TypeQ
    resolveInfixT1 :: InfixList -> Q Type
    resolveInfixT1 = [(Type, Name, Bool, Fixity)] -> InfixList -> Q Type
    go []
      where
        go :: [(Type,Name,Bool,Fixity)] -> InfixList -> TypeQ
        go :: [(Type, Name, Bool, Fixity)] -> InfixList -> Q Type
    go [(Type, Name, Bool, Fixity)]
    ts (ILNil Type
    u) = Type -> Q Type
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((Type -> (Type, Name, Bool, Fixity) -> Type)
    -> Type -> [(Type, Name, Bool, Fixity)] -> Type
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl (\Type
    acc (Type
    l,Name
    o,Bool
    p,Fixity
    _) -> Bool -> Name -> Type
    mkConT Bool
    p Name
    o Type -> Type -> Type
    `AppT` Type
    l Type -> Type -> Type
    `AppT` Type
    acc) Type
    u [(Type, Name, Bool, Fixity)]
    ts)
        go [(Type, Name, Bool, Fixity)]
    ts (ILCons Type
    l Name
    o Bool
    p InfixList
    r) =
          do ofx <- Fixity -> Maybe Fixity -> Fixity
    forall a. a -> Maybe a -> a
    fromMaybe Fixity
    defaultFixity (Maybe Fixity -> Fixity) -> Q (Maybe Fixity) -> Q Fixity
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Q (Maybe Fixity)
    reifyFixityCompat Name
    o
             let push = [(Type, Name, Bool, Fixity)] -> InfixList -> Q Type
    go ((Type
    l,Name
    o,Bool
    p,Fixity
    ofx)(Type, Name, Bool, Fixity)
    -> [(Type, Name, Bool, Fixity)] -> [(Type, Name, Bool, Fixity)]
    forall a. a -> [a] -> [a]
    :[(Type, Name, Bool, Fixity)]
    ts) InfixList
    r
             case ts of
               (Type
    l1,Name
    o1,Bool
    p1,Fixity
    o1fx):[(Type, Name, Bool, Fixity)]
    ts' ->
                 case Fixity -> Fixity -> Maybe Bool
    compareFixity Fixity
    o1fx Fixity
    ofx of
                   Just Bool
    True  -> [(Type, Name, Bool, Fixity)] -> InfixList -> Q Type
    go ((Bool -> Name -> Type
    mkConT Bool
    p1 Name
    o1 Type -> Type -> Type
    `AppT` Type
    l1 Type -> Type -> Type
    `AppT` Type
    l, Name
    o, Bool
    p, Fixity
    ofx)(Type, Name, Bool, Fixity)
    -> [(Type, Name, Bool, Fixity)] -> [(Type, Name, Bool, Fixity)]
    forall a. a -> [a] -> [a]
    :[(Type, Name, Bool, Fixity)]
    ts') InfixList
    r
                   Just Bool
    False -> Q Type
    push
                   Maybe Bool
    Nothing    -> String -> Q Type
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (Name -> Fixity -> Name -> Fixity -> String
    precedenceError Name
    o1 Fixity
    o1fx Name
    o Fixity
    ofx)
               [(Type, Name, Bool, Fixity)]
    _ -> Q Type
    push

        mkConT :: Bool -> Name -> Type
        mkConT :: Bool -> Name -> Type
    mkConT Bool
    promoted = if Bool
    promoted then Name -> Type
    PromotedT else Name -> Type
    ConT

        compareFixity :: Fixity -> Fixity -> Maybe Bool
        compareFixity :: Fixity -> Fixity -> Maybe Bool
    compareFixity (Fixity Int
    n1 FixityDirection
    InfixL) (Fixity Int
    n2 FixityDirection
    InfixL) = Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just (Int
    n1 Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    n2)
        compareFixity (Fixity Int
    n1 FixityDirection
    InfixR) (Fixity Int
    n2 FixityDirection
    InfixR) = Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just (Int
    n1 Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >  Int
    n2)
        compareFixity (Fixity Int
    n1 FixityDirection
    _     ) (Fixity Int
    n2 FixityDirection
    _     ) =
          case Int -> Int -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Int
    n1 Int
    n2 of
            Ordering
    GT -> Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    True
            Ordering
    LT -> Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    False
            Ordering
    EQ -> Maybe Bool
    forall a. Maybe a
    Nothing

        precedenceError :: Name -> Fixity -> Name -> Fixity -> String
        precedenceError :: Name -> Fixity -> Name -> Fixity -> String
    precedenceError Name
    o1 Fixity
    ofx1 Name
    o2 Fixity
    ofx2 =
          String
    "Precedence parsing error: cannot mix ‘" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
          Name -> String
    nameBase Name
    o1 String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "’ [" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Fixity -> String
    showFixity Fixity
    ofx1 String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "] and ‘" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
          Name -> String
    nameBase Name
    o2 String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "’ [" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Fixity -> String
    showFixity Fixity
    ofx2 String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
          String
    "] 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 :: InfixList -> Name -> Bool -> InfixList -> InfixList
    ilAppend (ILNil Type
    l)            Name
    o Bool
    p InfixList
    r = Type -> Name -> Bool -> InfixList -> InfixList
    ILCons Type
    l Name
    o Bool
    p InfixList
    r
    ilAppend (ILCons Type
    l1 Name
    o1 Bool
    p1 InfixList
    r1) Name
    o Bool
    p InfixList
    r = Type -> Name -> Bool -> InfixList -> InfixList
    ILCons Type
    l1 Name
    o1 Bool
    p1 (InfixList -> Name -> Bool -> InfixList -> InfixList
    ilAppend InfixList
    r1 Name
    o Bool
    p InfixList
    r)

    -- | Render a 'Fixity' as it would appear in Haskell source.
    --
    -- Example: @infixl 5@
    showFixity :: Fixity -> String
    showFixity :: Fixity -> String
    showFixity (Fixity Int
    n FixityDirection
    d) = FixityDirection -> String
    showFixityDirection FixityDirection
    d String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    n

    -- | Render a 'FixityDirection' like it would appear in Haskell source.
    --
    -- Examples: @infixl@ @infixr@ @infix@
    showFixityDirection :: FixityDirection -> String
    showFixityDirection :: FixityDirection -> String
    showFixityDirection FixityDirection
    InfixL = String
    "infixl"
    showFixityDirection FixityDirection
    InfixR = String
    "infixr"
    showFixityDirection FixityDirection
    InfixN = String
    "infix"

    takeFieldNames :: [(Name,a,b)] -> [Name]
    takeFieldNames :: forall a b. [(Name, a, b)] -> [Name]
    takeFieldNames [(Name, a, b)]
    xs = [Name
    a | (Name
    a,a
    _,b
    _) <- [(Name, a, b)]
    xs]

    takeFieldStrictness :: [(a,Bang,b)] -> [FieldStrictness]
    takeFieldStrictness :: forall a b. [(a, Bang, b)] -> [FieldStrictness]
    takeFieldStrictness [(a, Bang, b)]
    xs = [Bang -> FieldStrictness
    normalizeStrictness Bang
    a | (a
    _,Bang
    a,b
    _) <- [(a, Bang, b)]
    xs]

    takeFieldTypes :: [(a,b,Type)] -> [Type]
    takeFieldTypes :: forall a b. [(a, b, Type)] -> [Type]
    takeFieldTypes [(a, b, Type)]
    xs = [Type
    a | (a
    _,b
    _,Type
    a) <- [(a, b, Type)]
    xs]

    conHasRecord :: Name -> ConstructorInfo -> Bool
    conHasRecord :: Name -> ConstructorInfo -> Bool
    conHasRecord Name
    recName ConstructorInfo
    info =
      case ConstructorInfo -> ConstructorVariant
    constructorVariant ConstructorInfo
    info of
        ConstructorVariant
    NormalConstructor        -> Bool
    False
        ConstructorVariant
    InfixConstructor         -> Bool
    False
        RecordConstructor [Name]
    fields -> Name
    recName Name -> [Name] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Name]
    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 :: Type -> Type
    quantifyType Type
    t
      | [TyVarBndrSpec] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TyVarBndrSpec]
    tvbs
      = Type
    t
      | ForallT [TyVarBndrSpec]
    tvbs' [Type]
    ctxt' Type
    t' <- Type
    t -- Collapse two consecutive foralls (#63)
      = [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT ([TyVarBndrSpec]
    tvbs [TyVarBndrSpec] -> [TyVarBndrSpec] -> [TyVarBndrSpec]
    forall a. [a] -> [a] -> [a]
    ++ [TyVarBndrSpec]
    tvbs') [Type]
    ctxt' Type
    t'
      | Bool
    otherwise
      = [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT [TyVarBndrSpec]
    tvbs [] Type
    t
      where
        tvbs :: [TyVarBndrSpec]
    tvbs = Specificity -> [TyVarBndrUnit] -> [TyVarBndrSpec]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec ([TyVarBndrUnit] -> [TyVarBndrSpec])
    -> [TyVarBndrUnit] -> [TyVarBndrSpec]
    forall a b. (a -> b) -> a -> b
    $ [Type] -> [TyVarBndrUnit]
    freeVariablesWellScoped [Type
    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 :: [Type] -> [TyVarBndrUnit]
    freeVariablesWellScoped [Type]
    tys =
      let fvs :: [Name]
          fvs :: [Name]
    fvs = [Type] -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables [Type]
    tys

          varKindSigs :: Map Name Kind
          varKindSigs :: Map Name Type
    varKindSigs = (Type -> Map Name Type) -> [Type] -> Map Name Type
    forall m a. Monoid m => (a -> m) -> [a] -> m
    forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap Type -> Map Name Type
    go_ty [Type]
    tys
            where
              go_ty :: Type -> Map Name Kind
              go_ty :: Type -> Map Name Type
    go_ty (ForallT [TyVarBndrSpec]
    tvbs [Type]
    ctxt Type
    t) =
                (TyVarBndrSpec -> Map Name Type -> Map Name Type)
    -> Map Name Type -> [TyVarBndrSpec] -> Map Name Type
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\TyVarBndrSpec
    tvb -> Name -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete (TyVarBndrSpec -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName TyVarBndrSpec
    tvb))
                      ((Type -> Map Name Type) -> [Type] -> Map Name Type
    forall m a. Monoid m => (a -> m) -> [a] -> m
    forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap Type -> Map Name Type
    go_ty [Type]
    ctxt Map Name Type -> Map Name Type -> Map Name Type
    forall a. Monoid a => a -> a -> a
    `mappend` Type -> Map Name Type
    go_ty Type
    t) [TyVarBndrSpec]
    tvbs
              go_ty (AppT Type
    t1 Type
    t2) = Type -> Map Name Type
    go_ty Type
    t1 Map Name Type -> Map Name Type -> Map Name Type
    forall a. Monoid a => a -> a -> a
    `mappend` Type -> Map Name Type
    go_ty Type
    t2
              go_ty (SigT Type
    t Type
    k) =
                let kSigs :: Map Name Type
    kSigs = Type -> Map Name Type
    go_ty Type
    k
                in case Type
    t of
                     VarT Name
    n -> Name -> Type -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert Name
    n Type
    k Map Name Type
    kSigs
                     Type
    _      -> Type -> Map Name Type
    go_ty Type
    t Map Name Type -> Map Name Type -> Map Name Type
    forall a. Monoid a => a -> a -> a
    `mappend` Map Name Type
    kSigs
    #if MIN_VERSION_template_haskell(2,15,0)
              go_ty (AppKindT Type
    t Type
    k) = Type -> Map Name Type
    go_ty Type
    t Map Name Type -> Map Name Type -> Map Name Type
    forall a. Monoid a => a -> a -> a
    `mappend` Type -> Map Name Type
    go_ty Type
    k
              go_ty (ImplicitParamT String
    _ Type
    t) = Type -> Map Name Type
    go_ty Type
    t
    #endif
    #if MIN_VERSION_template_haskell(2,16,0)
              go_ty (ForallVisT [TyVarBndrUnit]
    tvbs Type
    t) =
                (TyVarBndrUnit -> Map Name Type -> Map Name Type)
    -> Map Name Type -> [TyVarBndrUnit] -> Map Name Type
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\TyVarBndrUnit
    tvb -> Name -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete (TyVarBndrUnit -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName TyVarBndrUnit
    tvb)) (Type -> Map Name Type
    go_ty Type
    t) [TyVarBndrUnit]
    tvbs
    #endif
              go_ty Type
    _ = Map Name Type
    forall a. Monoid a => a
    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 :: [Name] -> [Name]
    scopedSort = [Name] -> [Set Name] -> [Name] -> [Name]
    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 :: [Name] -> [Set Name] -> [Name] -> [Name]
    go [Name]
    acc [Set Name]
    _fv_list [] = [Name] -> [Name]
    forall a. [a] -> [a]
    reverse [Name]
    acc
          go [Name]
    acc  [Set Name]
    fv_list (Name
    tv:[Name]
    tvs)
            = [Name] -> [Set Name] -> [Name] -> [Name]
    go [Name]
    acc' [Set Name]
    fv_list' [Name]
    tvs
            where
              ([Name]
    acc', [Set Name]
    fv_list') = Name -> [Name] -> [Set Name] -> ([Name], [Set Name])
    insert Name
    tv [Name]
    acc [Set Name]
    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 :: Name -> [Name] -> [Set Name] -> ([Name], [Set Name])
    insert Name
    tv []     []         = ([Name
    tv], [Name -> Set Name
    kindFVSet Name
    tv])
          insert Name
    tv (Name
    a:[Name]
    as) (Set Name
    fvs:[Set Name]
    fvss)
            | Name
    tv Name -> Set Name -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set Name
    fvs
            , ([Name]
    as', [Set Name]
    fvss') <- Name -> [Name] -> [Set Name] -> ([Name], [Set Name])
    insert Name
    tv [Name]
    as [Set Name]
    fvss
            = (Name
    aName -> [Name] -> [Name]
    forall a. a -> [a] -> [a]
    :[Name]
    as', Set Name
    fvs Set Name -> Set Name -> Set Name
    forall a. Ord a => Set a -> Set a -> Set a
    `Set.union` Set Name
    fv_tv Set Name -> [Set Name] -> [Set Name]
    forall a. a -> [a] -> [a]
    : [Set Name]
    fvss')

            | Bool
    otherwise
            = (Name
    tvName -> [Name] -> [Name]
    forall a. a -> [a] -> [a]
    :Name
    aName -> [Name] -> [Name]
    forall a. a -> [a] -> [a]
    :[Name]
    as, Set Name
    fvs Set Name -> Set Name -> Set Name
    forall a. Ord a => Set a -> Set a -> Set a
    `Set.union` Set Name
    fv_tv Set Name -> [Set Name] -> [Set Name]
    forall a. a -> [a] -> [a]
    : Set Name
    fvs Set Name -> [Set Name] -> [Set Name]
    forall a. a -> [a] -> [a]
    : [Set Name]
    fvss)
            where
              fv_tv :: Set Name
    fv_tv = Name -> Set Name
    kindFVSet Name
    tv

             -- lists not in correspondence
          insert Name
    _ [Name]
    _ [Set Name]
    _ = String -> ([Name], [Set Name])
    forall a. HasCallStack => String -> a
    error String
    "scopedSort"

          kindFVSet :: Name -> Set Name
    kindFVSet Name
    n =
            Set Name -> (Type -> Set Name) -> Maybe Type -> Set Name
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Set Name
    forall a. Set a
    Set.empty ([Name] -> Set Name
    forall a. Ord a => [a] -> Set a
    Set.fromList ([Name] -> Set Name) -> (Type -> [Name]) -> Type -> Set Name
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables) (Name -> Map Name Type -> Maybe Type
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup Name
    n Map Name Type
    varKindSigs)
          ascribeWithKind :: Name -> TyVarBndr flag
    ascribeWithKind Name
    n =
            TyVarBndr flag
    -> (Type -> TyVarBndr flag) -> Maybe Type -> TyVarBndr flag
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (Name -> TyVarBndr flag
    forall flag. DefaultBndrFlag flag => Name -> TyVarBndr flag
    plainTV Name
    n) (Name -> Type -> TyVarBndr flag
    forall flag. DefaultBndrFlag flag => Name -> Type -> TyVarBndr flag
    kindedTV Name
    n) (Name -> Map Name Type -> Maybe Type
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup Name
    n Map Name Type
    varKindSigs)

      in (Name -> TyVarBndrUnit) -> [Name] -> [TyVarBndrUnit]
    forall a b. (a -> b) -> [a] -> [b]
    map Name -> TyVarBndrUnit
    forall flag. DefaultBndrFlag flag => Name -> TyVarBndr flag
    ascribeWithKind ([Name] -> [TyVarBndrUnit]) -> [Name] -> [TyVarBndrUnit]
    forall a b. (a -> b) -> a -> b
    $ [Name] -> [Name]
    scopedSort [Name]
    fvs

    -- | Substitute all of the free variables in a type with fresh ones
    freshenFreeVariables :: Type -> Q Type
    freshenFreeVariables :: Type -> Q Type
    freshenFreeVariables Type
    t =
      do let xs :: [(Name, Q Type)]
    xs = [ (Name
    n, Name -> Type
    VarT (Name -> Type) -> Q Name -> Q Type
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> String -> Q Name
    forall (m :: * -> *). Quote m => String -> m Name
    newName (Name -> String
    nameBase Name
    n)) | Name
    n <- Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t]
         subst <- Map Name (Q Type) -> Q (Map Name Type)
    forall (t :: * -> *) (m :: * -> *) a.
    (Traversable t, Monad m) =>
    t (m a) -> m (t a)
    forall (m :: * -> *) a. Monad m => Map Name (m a) -> m (Map Name a)
    T.sequence ([(Name, Q Type)] -> Map Name (Q Type)
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [(Name, Q Type)]
    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 :: [a] -> [Name]
    freeVariables     = [Name] -> [Name]
    forall a. Eq a => [a] -> [a]
    nub ([Name] -> [Name]) -> ([a] -> [Name]) -> [a] -> [Name]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[Name]] -> [Name]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Name]] -> [Name]) -> ([a] -> [[Name]]) -> [a] -> [Name]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> [Name]) -> [a] -> [[Name]]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables
      applySubstitution :: Map Name Type -> [a] -> [a]
    applySubstitution = (a -> a) -> [a] -> [a]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> a) -> [a] -> [a])
    -> (Map Name Type -> a -> a) -> Map Name Type -> [a] -> [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Map Name Type -> a -> a
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution

    instance TypeSubstitution Type where
      applySubstitution :: Map Name Type -> Type -> Type
    applySubstitution Map Name Type
    subst = Type -> Type
    go
        where
          go :: Type -> Type
    go (ForallT [TyVarBndrSpec]
    tvs [Type]
    context Type
    t) =
            let (Map Name Type
    subst', [TyVarBndrSpec]
    tvs') = Map Name Type
    -> [TyVarBndrSpec] -> (Map Name Type, [TyVarBndrSpec])
    forall flag.
    Map Name Type
    -> [TyVarBndr_ flag] -> (Map Name Type, [TyVarBndr_ flag])
    substTyVarBndrs Map Name Type
    subst [TyVarBndrSpec]
    tvs in
            [TyVarBndrSpec] -> [Type] -> Type -> Type
    ForallT [TyVarBndrSpec]
    tvs'
                    (Map Name Type -> [Type] -> [Type]
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst' [Type]
    context)
                    (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst' Type
    t)
          go (AppT Type
    f Type
    x)      = Type -> Type -> Type
    AppT (Type -> Type
    go Type
    f) (Type -> Type
    go Type
    x)
          go (SigT Type
    t Type
    k)      = Type -> Type -> Type
    SigT (Type -> Type
    go Type
    t) (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst Type
    k) -- k could be Kind
          go (VarT Name
    v)        = Type -> Name -> Map Name Type -> Type
    forall k a. Ord k => a -> k -> Map k a -> a
    Map.findWithDefault (Name -> Type
    VarT Name
    v) Name
    v Map Name Type
    subst
          go (InfixT Type
    l Name
    c Type
    r)  = Type -> Name -> Type -> Type
    InfixT (Type -> Type
    go Type
    l) Name
    c (Type -> Type
    go Type
    r)
          go (UInfixT Type
    l Name
    c Type
    r) = Type -> Name -> Type -> Type
    UInfixT (Type -> Type
    go Type
    l) Name
    c (Type -> Type
    go Type
    r)
          go (ParensT Type
    t)     = Type -> Type
    ParensT (Type -> Type
    go Type
    t)
    #if MIN_VERSION_template_haskell(2,15,0)
          go (AppKindT Type
    t Type
    k)  = Type -> Type -> Type
    AppKindT (Type -> Type
    go Type
    t) (Type -> Type
    go Type
    k)
          go (ImplicitParamT String
    n Type
    t)
                             = String -> Type -> Type
    ImplicitParamT String
    n (Type -> Type
    go Type
    t)
    #endif
    #if MIN_VERSION_template_haskell(2,16,0)
          go (ForallVisT [TyVarBndrUnit]
    tvs Type
    t) =
            let (Map Name Type
    subst', [TyVarBndrUnit]
    tvs') = Map Name Type
    -> [TyVarBndrUnit] -> (Map Name Type, [TyVarBndrUnit])
    forall flag.
    Map Name Type
    -> [TyVarBndr_ flag] -> (Map Name Type, [TyVarBndr_ flag])
    substTyVarBndrs Map Name Type
    subst [TyVarBndrUnit]
    tvs in
            [TyVarBndrUnit] -> Type -> Type
    ForallVisT [TyVarBndrUnit]
    tvs'
                       (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst' Type
    t)
    #endif
    #if MIN_VERSION_template_haskell(2,19,0)
          go (PromotedInfixT Type
    l Name
    c Type
    r)
                             = Type -> Name -> Type -> Type
    PromotedInfixT (Type -> Type
    go Type
    l) Name
    c (Type -> Type
    go Type
    r)
          go (PromotedUInfixT Type
    l Name
    c Type
    r)
                             = Type -> Name -> Type -> Type
    PromotedUInfixT (Type -> Type
    go Type
    l) Name
    c (Type -> Type
    go Type
    r)
    #endif
          go Type
    t               = Type
    t

          subst_tvbs :: [TyVarBndr_ flag] -> (Map Name Type -> a) -> a
          subst_tvbs :: forall flag a. [TyVarBndr_ flag] -> (Map Name Type -> a) -> a
    subst_tvbs [TyVarBndr_ flag]
    tvs Map Name Type -> a
    k = Map Name Type -> a
    k (Map Name Type -> a) -> Map Name Type -> a
    forall a b. (a -> b) -> a -> b
    $ (Map Name Type -> Name -> Map Name Type)
    -> Map Name Type -> [Name] -> Map Name Type
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' ((Name -> Map Name Type -> Map Name Type)
    -> Map Name Type -> Name -> Map Name Type
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Name -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete) Map Name Type
    subst ((TyVarBndr_ flag -> Name) -> [TyVarBndr_ flag] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr_ flag -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName [TyVarBndr_ flag]
    tvs)

      freeVariables :: Type -> [Name]
    freeVariables Type
    t =
        case Type
    t of
          ForallT [TyVarBndrSpec]
    tvs [Type]
    context Type
    t' ->
              [TyVarBndrSpec] -> [Name] -> [Name]
    forall flag. [TyVarBndr_ flag] -> [Name] -> [Name]
    fvs_under_forall [TyVarBndrSpec]
    tvs ([Type] -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables [Type]
    context [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t')
          AppT Type
    f Type
    x      -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    f [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    x
          SigT Type
    t' Type
    k     -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t' [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    k
          VarT Name
    v        -> [Name
    v]
          InfixT Type
    l Name
    _ Type
    r  -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    l [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    r
          UInfixT Type
    l Name
    _ Type
    r -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    l [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    r
          ParensT Type
    t'    -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t'
    #if MIN_VERSION_template_haskell(2,15,0)
          AppKindT Type
    t Type
    k  -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    k
          ImplicitParamT String
    _ Type
    t
                        -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t
    #endif
    #if MIN_VERSION_template_haskell(2,16,0)
          ForallVisT [TyVarBndrUnit]
    tvs Type
    t'
                        -> [TyVarBndrUnit] -> [Name] -> [Name]
    forall flag. [TyVarBndr_ flag] -> [Name] -> [Name]
    fvs_under_forall [TyVarBndrUnit]
    tvs (Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t')
    #endif
    #if MIN_VERSION_template_haskell(2,19,0)
          PromotedInfixT Type
    l Name
    _ Type
    r
                        -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    l [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    r
          PromotedUInfixT Type
    l Name
    _ Type
    r
                        -> Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    l [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    r
    #endif
          Type
    _             -> []
        where
          fvs_under_forall :: [TyVarBndr_ flag] -> [Name] -> [Name]
          fvs_under_forall :: forall flag. [TyVarBndr_ flag] -> [Name] -> [Name]
    fvs_under_forall [TyVarBndr_ flag]
    tvs [Name]
    fvs =
            ([Type] -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables ((TyVarBndr_ flag -> Type) -> [TyVarBndr_ flag] -> [Type]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr_ flag -> Type
    forall flag. TyVarBndr_ flag -> Type
    tvKind [TyVarBndr_ flag]
    tvs) [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` [Name]
    fvs)
            [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ (TyVarBndr_ flag -> Name) -> [TyVarBndr_ flag] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr_ flag -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName [TyVarBndr_ flag]
    tvs

    instance TypeSubstitution ConstructorInfo where
      freeVariables :: ConstructorInfo -> [Name]
    freeVariables ConstructorInfo
    ci =
          ([Type] -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables ((TyVarBndrUnit -> Type) -> [TyVarBndrUnit] -> [Type]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrUnit -> Type
    forall flag. TyVarBndr_ flag -> Type
    tvKind (ConstructorInfo -> [TyVarBndrUnit]
    constructorVars ConstructorInfo
    ci))
              [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` [Type] -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables (ConstructorInfo -> [Type]
    constructorContext ConstructorInfo
    ci)
              [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    `union` [Type] -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables (ConstructorInfo -> [Type]
    constructorFields ConstructorInfo
    ci))
          [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ (TyVarBndrUnit -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName (TyVarBndrUnit -> Name) -> [TyVarBndrUnit] -> [Name]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ConstructorInfo -> [TyVarBndrUnit]
    constructorVars ConstructorInfo
    ci)

      applySubstitution :: Map Name Type -> ConstructorInfo -> ConstructorInfo
    applySubstitution Map Name Type
    subst ConstructorInfo
    ci =
        let subst' :: Map Name Type
    subst' = (Map Name Type -> Name -> Map Name Type)
    -> Map Name Type -> [Name] -> Map Name Type
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' ((Name -> Map Name Type -> Map Name Type)
    -> Map Name Type -> Name -> Map Name Type
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Name -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete) Map Name Type
    subst ((TyVarBndrUnit -> Name) -> [TyVarBndrUnit] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrUnit -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName (ConstructorInfo -> [TyVarBndrUnit]
    constructorVars ConstructorInfo
    ci)) in
        ConstructorInfo
    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 :: forall flag.
    Map Name Type
    -> [TyVarBndr_ flag] -> (Map Name Type, [TyVarBndr_ flag])
    substTyVarBndrs = (Map Name Type
     -> TyVarBndr_ flag -> (Map Name Type, TyVarBndr_ flag))
    -> Map Name Type
    -> [TyVarBndr_ flag]
    -> (Map Name Type, [TyVarBndr_ flag])
    forall (t :: * -> *) s a b.
    Traversable t =>
    (s -> a -> (s, b)) -> s -> t a -> (s, t b)
    mapAccumL Map Name Type
    -> TyVarBndr_ flag -> (Map Name Type, TyVarBndr_ flag)
    forall flag.
    Map Name Type
    -> TyVarBndr_ flag -> (Map Name Type, TyVarBndr_ flag)
    substTyVarBndr

    -- | The workhorse for 'substTyVarBndrs'.
    substTyVarBndr :: Map Name Type -> TyVarBndr_ flag -> (Map Name Type, TyVarBndr_ flag)
    substTyVarBndr :: forall flag.
    Map Name Type
    -> TyVarBndr_ flag -> (Map Name Type, TyVarBndr_ flag)
    substTyVarBndr Map Name Type
    subst TyVarBndr_ flag
    tvb
      | Name
    tvbName Name -> Map Name Type -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    `Map.member` Map Name Type
    subst
      = (Name -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete Name
    tvbName Map Name Type
    subst, (Type -> Type) -> TyVarBndr_ flag -> TyVarBndr_ flag
    forall flag. (Type -> Type) -> TyVarBndr_ flag -> TyVarBndr_ flag
    mapTVKind (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst) TyVarBndr_ flag
    tvb)
      | Name
    tvbName Name -> Set Name -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.notMember` Set Name
    substRangeFVs
      = (Map Name Type
    subst, (Type -> Type) -> TyVarBndr_ flag -> TyVarBndr_ flag
    forall flag. (Type -> Type) -> TyVarBndr_ flag -> TyVarBndr_ flag
    mapTVKind (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst) TyVarBndr_ flag
    tvb)
      | Bool
    otherwise
      = let tvbName' :: Name
    tvbName' = Name -> Name
    evade Name
    tvbName in
        ( Name -> Type -> Map Name Type -> Map Name Type
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert Name
    tvbName (Name -> Type
    VarT Name
    tvbName') Map Name Type
    subst
        , (Name -> Name)
    -> (flag -> flag)
    -> (Type -> Type)
    -> TyVarBndr_ flag
    -> TyVarBndr_ flag
    forall flag flag'.
    (Name -> Name)
    -> (flag -> flag')
    -> (Type -> Type)
    -> TyVarBndr_ flag
    -> TyVarBndr_ flag'
    mapTV (\Name
    _ -> Name
    tvbName') flag -> flag
    forall a. a -> a
    id (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst) TyVarBndr_ flag
    tvb
        )
      where
        tvbName :: Name
        tvbName :: Name
    tvbName = TyVarBndr_ flag -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName TyVarBndr_ flag
    tvb

        substRangeFVs :: Set Name
        substRangeFVs :: Set Name
    substRangeFVs = [Name] -> Set Name
    forall a. Ord a => [a] -> Set a
    Set.fromList ([Name] -> Set Name) -> [Name] -> Set Name
    forall a b. (a -> b) -> a -> b
    $ [Type] -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables ([Type] -> [Name]) -> [Type] -> [Name]
    forall a b. (a -> b) -> a -> b
    $ Map Name Type -> [Type]
    forall k a. Map k a -> [a]
    Map.elems Map Name Type
    subst

        evade :: Name -> Name
        evade :: Name -> Name
    evade Name
    n | Name
    n Name -> Set Name -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set Name
    substRangeFVs
                = Name -> Name
    evade (Name -> Name) -> Name -> Name
    forall a b. (a -> b) -> a -> b
    $ Name -> Name
    bump Name
    n
                | Bool
    otherwise
                = Name
    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 :: Name -> Name
    bump Name
    n = String -> Name
    mkName (String -> Name) -> String -> Name
    forall a b. (a -> b) -> a -> b
    $ Char
    'f'Char -> ShowS
    forall a. a -> [a] -> [a]
    :Name -> String
    nameBase Name
    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 :: forall flag.
    Map Name Type -> [TyVarBndr_ flag] -> [TyVarBndr_ flag]
    substTyVarBndrKinds Map Name Type
    subst = (TyVarBndr_ flag -> TyVarBndr_ flag)
    -> [TyVarBndr_ flag] -> [TyVarBndr_ flag]
    forall a b. (a -> b) -> [a] -> [b]
    map (Map Name Type -> TyVarBndr_ flag -> TyVarBndr_ flag
    forall flag. Map Name Type -> TyVarBndr_ flag -> TyVarBndr_ flag
    substTyVarBndrKind Map Name Type
    subst)

    -- | The workhorse for 'substTyVarBndrKinds'.
    substTyVarBndrKind :: Map Name Type -> TyVarBndr_ flag -> TyVarBndr_ flag
    substTyVarBndrKind :: forall flag. Map Name Type -> TyVarBndr_ flag -> TyVarBndr_ flag
    substTyVarBndrKind Map Name Type
    subst = (Type -> Type) -> TyVarBndr_ flag -> TyVarBndr_ flag
    forall flag. (Type -> Type) -> TyVarBndr_ flag -> TyVarBndr_ flag
    mapTVKind (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    subst)

    ------------------------------------------------------------------------

    combineSubstitutions :: Map Name Type -> Map Name Type -> Map Name Type
    combineSubstitutions :: Map Name Type -> Map Name Type -> Map Name Type
    combineSubstitutions Map Name Type
    x Map Name Type
    y = Map Name Type -> Map Name Type -> Map Name Type
    forall k a. Ord k => Map k a -> Map k a -> Map k a
    Map.union ((Type -> Type) -> Map Name Type -> Map Name Type
    forall a b. (a -> b) -> Map Name a -> Map Name b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    y) Map Name Type
    x) Map Name Type
    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 :: [Type] -> Q (Map Name Type)
    unifyTypes [] = Map Name Type -> Q (Map Name Type)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Map Name Type
    forall k a. Map k a
    Map.empty
    unifyTypes (Type
    t:[Type]
    ts) =
      do t':ts' <- (Type -> Q Type) -> [Type] -> Q [Type]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Type -> Q Type
    resolveTypeSynonyms (Type
    tType -> [Type] -> [Type]
    forall a. a -> [a] -> [a]
    :[Type]
    ts)
         let aux Map Name Type
    sub Type
    u =
               do sub' <- Type -> Type -> Either (Type, Type) (Map Name Type)
    unify' (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    sub Type
    t')
                                 (Map Name Type -> Type -> Type
    forall a. TypeSubstitution a => Map Name Type -> a -> a
    applySubstitution Map Name Type
    sub Type
    u)
                  return (combineSubstitutions sub sub')

         case foldM aux Map.empty ts' of
           Right Map Name Type
    m -> Map Name Type -> Q (Map Name Type)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Map Name Type
    m
           Left (Type
    x,Type
    y) ->
             String -> Q (Map Name Type)
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q (Map Name Type)) -> String -> Q (Map Name Type)
    forall a b. (a -> b) -> a -> b
    $ String -> ShowS
    showString String
    "Unable to unify types "
                  ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Type -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec Int
    11 Type
    x
                  ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ShowS
    showString String
    " and "
                  ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Type -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec Int
    11 Type
    y
                  ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ String
    ""

    unify' :: Type -> Type -> Either (Type,Type) (Map Name Type)

    unify' :: Type -> Type -> Either (Type, Type) (Map Name Type)
    unify' (VarT Name
    n) (VarT Name
    m) | Name
    n Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    m = Map Name Type -> Either (Type, Type) (Map Name Type)
    forall a. a -> Either (Type, Type) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Map Name Type
    forall k a. Map k a
    Map.empty
    unify' (VarT Name
    n) Type
    t | Name
    n Name -> [Name] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t = (Type, Type) -> Either (Type, Type) (Map Name Type)
    forall a b. a -> Either a b
    Left (Name -> Type
    VarT Name
    n, Type
    t)
                      | Bool
    otherwise                = Map Name Type -> Either (Type, Type) (Map Name Type)
    forall a b. b -> Either a b
    Right (Name -> Type -> Map Name Type
    forall k a. k -> a -> Map k a
    Map.singleton Name
    n Type
    t)
    unify' Type
    t (VarT Name
    n) | Name
    n Name -> [Name] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` Type -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Type
    t = (Type, Type) -> Either (Type, Type) (Map Name Type)
    forall a b. a -> Either a b
    Left (Name -> Type
    VarT Name
    n, Type
    t)
                      | Bool
    otherwise                = Map Name Type -> Either (Type, Type) (Map Name Type)
    forall a b. b -> Either a b
    Right (Name -> Type -> Map Name Type
    forall k a. k -> a -> Map k a
    Map.singleton Name
    n Type
    t)

    unify' (AppT Type
    f1 Type
    x1) (AppT Type
    f2 Type
    x2) =
      do sub1 <- Type -> Type -> Either (Type, Type) (Map Name Type)
    unify' Type
    f1 Type
    f2
         sub2 <- unify' (applySubstitution sub1 x1) (applySubstitution sub1 x2)
         Right (combineSubstitutions sub1 sub2)

    -- Doesn't unify kind signatures
    unify' (SigT Type
    t Type
    _) Type
    u = Type -> Type -> Either (Type, Type) (Map Name Type)
    unify' Type
    t Type
    u
    unify' Type
    t (SigT Type
    u Type
    _) = Type -> Type -> Either (Type, Type) (Map Name Type)
    unify' Type
    t Type
    u

    -- only non-recursive cases should remain at this point
    unify' Type
    t Type
    u
      | Type
    t Type -> Type -> Bool
    forall a. Eq a => a -> a -> Bool
    == Type
    u    = Map Name Type -> Either (Type, Type) (Map Name Type)
    forall a b. b -> Either a b
    Right Map Name Type
    forall k a. Map k a
    Map.empty
      | Bool
    otherwise = (Type, Type) -> Either (Type, Type) (Map Name Type)
    forall a b. a -> Either a b
    Left (Type
    t,Type
    u)

    -- | Construct an equality constraint. The implementation of 'Pred' varies
    -- across versions of Template Haskell.
    equalPred :: Type -> Type -> Pred
    equalPred :: Type -> Type -> Type
    equalPred Type
    x Type
    y = Type -> Type -> Type
    AppT (Type -> Type -> Type
    AppT Type
    EqualityT Type
    x) Type
    y

    -- | Construct a typeclass constraint. The implementation of 'Pred' varies
    -- across versions of Template Haskell.
    classPred :: Name {- ^ class -} -> [Type] {- ^ parameters -} -> Pred
    classPred :: Name -> [Type] -> Type
    classPred = (Type -> Type -> Type) -> Type -> [Type] -> Type
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Type -> Type -> Type
    AppT (Type -> [Type] -> Type)
    -> (Name -> Type) -> Name -> [Type] -> Type
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> Type
    ConT

    -- | Match a 'Pred' representing an equality constraint. Returns
    -- arguments to the equality constraint if successful.
    asEqualPred :: Pred -> Maybe (Type,Type)
    asEqualPred :: Type -> Maybe (Type, Type)
    asEqualPred (Type
    EqualityT `AppT` Type
    x `AppT` Type
    y)                    = (Type, Type) -> Maybe (Type, Type)
    forall a. a -> Maybe a
    Just (Type
    x,Type
    y)
    asEqualPred (ConT Name
    eq   `AppT` Type
    x `AppT` Type
    y) | Name
    eq Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    eqTypeName = (Type, Type) -> Maybe (Type, Type)
    forall a. a -> Maybe a
    Just (Type
    x,Type
    y)
    asEqualPred Type
    _                                                = Maybe (Type, Type)
    forall a. Maybe a
    Nothing

    -- | Match a 'Pred' representing a class constraint.
    -- Returns the classname and parameters if successful.
    asClassPred :: Pred -> Maybe (Name, [Type])
    asClassPred :: Type -> Maybe (Name, [Type])
    asClassPred Type
    t =
      case Type -> NonEmpty Type
    decomposeType Type
    t of
        ConT Name
    f :| [Type]
    xs | Name
    f Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Name
    eqTypeName -> (Name, [Type]) -> Maybe (Name, [Type])
    forall a. a -> Maybe a
    Just (Name
    f,[Type]
    xs)
        NonEmpty Type
    _                              -> Maybe (Name, [Type])
    forall a. Maybe a
    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 :: Bool
    isReified    = Bool
    True
    isn'tReified :: Bool
    isn'tReified = Bool
    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 :: Bool -> DatatypeInfo -> DatatypeInfo
    giveDIVarsStarKinds Bool
    isReified DatatypeInfo
    info =
      DatatypeInfo
    info { datatypeVars      = map (giveTyVarBndrStarKind isReified) (datatypeVars info)
           , datatypeInstTypes = map (giveTypeStarKind isReified) (datatypeInstTypes info) }

    giveCIVarsStarKinds :: IsReifiedDec -> ConstructorInfo -> ConstructorInfo
    giveCIVarsStarKinds :: Bool -> ConstructorInfo -> ConstructorInfo
    giveCIVarsStarKinds Bool
    isReified ConstructorInfo
    info =
      ConstructorInfo
    info { constructorVars = map (giveTyVarBndrStarKind isReified) (constructorVars info) }

    giveTyVarBndrStarKind :: IsReifiedDec ->  TyVarBndrUnit -> TyVarBndrUnit
    giveTyVarBndrStarKind :: Bool -> TyVarBndrUnit -> TyVarBndrUnit
    giveTyVarBndrStarKind Bool
    isReified TyVarBndrUnit
    tvb
      | Bool
    isReified
      = (Name -> TyVarBndrUnit)
    -> (Name -> Type -> TyVarBndrUnit)
    -> TyVarBndrUnit
    -> TyVarBndrUnit
    forall r flag.
    (Name -> r) -> (Name -> Type -> r) -> TyVarBndr_ flag -> r
    elimTV (\Name
    n -> Name -> Type -> TyVarBndrUnit
    forall flag. DefaultBndrFlag flag => Name -> Type -> TyVarBndr flag
    kindedTV Name
    n Type
    starK) (\Name
    _ Type
    _ -> TyVarBndrUnit
    tvb) TyVarBndrUnit
    tvb
      | Bool
    otherwise
      = TyVarBndrUnit
    tvb

    giveTypeStarKind :: IsReifiedDec -> Type -> Type
    giveTypeStarKind :: Bool -> Type -> Type
    giveTypeStarKind Bool
    isReified Type
    t
      | Bool
    isReified
      = case Type
    t of
          VarT Name
    n -> Type -> Type -> Type
    SigT Type
    t Type
    starK
          Type
    _      -> Type
    t
      | Bool
    otherwise
      = Type
    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 :: DatatypeInfo -> Q DatatypeInfo
    repair13618 DatatypeInfo
    info =
      do s <- Map Name (Q Type) -> Q (Map Name Type)
    forall (t :: * -> *) (m :: * -> *) a.
    (Traversable t, Monad m) =>
    t (m a) -> m (t a)
    forall (m :: * -> *) a. Monad m => Map Name (m a) -> m (Map Name a)
    T.sequence ([(Name, Q Type)] -> Map Name (Q Type)
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [(Name, Q Type)]
    substList)
         return info { datatypeCons = applySubstitution s (datatypeCons info) }

      where
        used :: [Name]
    used  = [ConstructorInfo] -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables (DatatypeInfo -> [ConstructorInfo]
    datatypeCons DatatypeInfo
    info)
        bound :: [Name]
    bound = (TyVarBndrUnit -> Name) -> [TyVarBndrUnit] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrUnit -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName (DatatypeInfo -> [TyVarBndrUnit]
    datatypeVars DatatypeInfo
    info)
        free :: [Name]
    free  = [Name]
    used [Name] -> [Name] -> [Name]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ [Name]
    bound

        substList :: [(Name, Q Type)]
    substList =
          [ (Name
    u, Name -> [Name] -> Q Type
    forall {m :: * -> *} {a}.
    (Quote m, MonadFail m, Show a) =>
    a -> [Name] -> m Type
    substEntry Name
    u [Name]
    vs)
          | Name
    u <- [Name]
    free
          , let vs :: [Name]
    vs = [Name
    v | Name
    v <- [Name]
    bound, Name -> String
    nameBase Name
    v String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name -> String
    nameBase Name
    u]
          ]

        substEntry :: a -> [Name] -> m Type
    substEntry a
    _ [Name
    v] = Name -> m Type
    forall (m :: * -> *). Quote m => Name -> m Type
    varT Name
    v
        substEntry a
    u []  = String -> m Type
    forall a. String -> m a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String
    "Impossible free variable: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ a -> String
    forall a. Show a => a -> String
    show a
    u)
        substEntry a
    u [Name]
    _   = String -> m Type
    forall a. String -> m a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String
    "Ambiguous free variable: "  String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ a -> String
    forall a. Show a => a -> String
    show a
    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 :: Q [Type]
    -> Name -> [TyVarBndr BndrVis] -> [ConQ] -> [Name] -> Q Dec
    dataDCompat Q [Type]
    c Name
    n [TyVarBndr BndrVis]
    ts [ConQ]
    cs [Name]
    ds =
      Q [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> [ConQ]
    -> [Q DerivClause]
    -> Q Dec
    forall (m :: * -> *).
    Quote m =>
    m [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> [m Con]
    -> [m DerivClause]
    -> m Dec
    dataD Q [Type]
    c Name
    n [TyVarBndr BndrVis]
    ts Maybe Type
    forall a. Maybe a
    Nothing [ConQ]
    cs
        (if [Name] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Name]
    ds then [] else [Maybe DerivStrategy -> [Q Type] -> Q DerivClause
    forall (m :: * -> *).
    Quote m =>
    Maybe DerivStrategy -> [m Type] -> m DerivClause
    derivClause Maybe DerivStrategy
    forall a. Maybe a
    Nothing ((Name -> Q Type) -> [Name] -> [Q Type]
    forall a b. (a -> b) -> [a] -> [b]
    map Name -> Q Type
    forall (m :: * -> *). Quote m => Name -> m Type
    conT [Name]
    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 :: Q [Type] -> Name -> [TyVarBndr BndrVis] -> ConQ -> [Name] -> Q Dec
    newtypeDCompat Q [Type]
    c Name
    n [TyVarBndr BndrVis]
    ts ConQ
    cs [Name]
    ds =
      Q [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> ConQ
    -> [Q DerivClause]
    -> Q Dec
    forall (m :: * -> *).
    Quote m =>
    m [Type]
    -> Name
    -> [TyVarBndr BndrVis]
    -> Maybe Type
    -> m Con
    -> [m DerivClause]
    -> m Dec
    newtypeD Q [Type]
    c Name
    n [TyVarBndr BndrVis]
    ts Maybe Type
    forall a. Maybe a
    Nothing ConQ
    cs
        (if [Name] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Name]
    ds then [] else [Maybe DerivStrategy -> [Q Type] -> Q DerivClause
    forall (m :: * -> *).
    Quote m =>
    Maybe DerivStrategy -> [m Type] -> m DerivClause
    derivClause Maybe DerivStrategy
    forall a. Maybe a
    Nothing ((Name -> Q Type) -> [Name] -> [Q Type]
    forall a b. (a -> b) -> [a] -> [b]
    map Name -> Q Type
    forall (m :: * -> *). Quote m => Name -> m Type
    conT [Name]
    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 :: Name -> Maybe [Q TyVarBndrUnit] -> [Q Type] -> Q Type -> Q Dec
    tySynInstDCompat Name
    n Maybe [Q TyVarBndrUnit]
    mtvbs [Q Type]
    ps Q Type
    r = TySynEqn -> Dec
    TySynInstD (TySynEqn -> Dec) -> Q TySynEqn -> Q Dec
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Maybe [TyVarBndrUnit] -> Type -> Type -> TySynEqn
    TySynEqn (Maybe [TyVarBndrUnit] -> Type -> Type -> TySynEqn)
    -> Q (Maybe [TyVarBndrUnit]) -> Q (Type -> Type -> TySynEqn)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ([Q TyVarBndrUnit] -> Q [TyVarBndrUnit])
    -> Maybe [Q TyVarBndrUnit] -> Q (Maybe [TyVarBndrUnit])
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Maybe a -> m (Maybe b)
    mapM [Q TyVarBndrUnit] -> Q [TyVarBndrUnit]
    forall (t :: * -> *) (m :: * -> *) a.
    (Traversable t, Monad m) =>
    t (m a) -> m (t a)
    forall (m :: * -> *) a. Monad m => [m a] -> m [a]
    sequence Maybe [Q TyVarBndrUnit]
    mtvbs
                                                             Q (Type -> Type -> TySynEqn) -> Q Type -> Q (Type -> TySynEqn)
    forall a b. Q (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> (Q Type -> Q Type -> Q Type) -> Q Type -> [Q Type] -> Q Type
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' Q Type -> Q Type -> Q Type
    forall (m :: * -> *). Quote m => m Type -> m Type -> m Type
    appT (Name -> Q Type
    forall (m :: * -> *). Quote m => Name -> m Type
    conT Name
    n) [Q Type]
    ps
                                                             Q (Type -> TySynEqn) -> Q Type -> Q TySynEqn
    forall a b. Q (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Q Type
    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 :: Int -> String -> Maybe (Q Dec)
    pragLineDCompat Int
    ln String
    fn = Q Dec -> Maybe (Q Dec)
    forall a. a -> Maybe a
    Just (Int -> String -> Q Dec
    forall (m :: * -> *). Quote m => Int -> String -> m Dec
    pragLineD Int
    ln String
    fn)

    arrowKCompat :: Kind -> Kind -> Kind
    arrowKCompat :: Type -> Type -> Type
    arrowKCompat Type
    x Type
    y = Type
    arrowK Type -> Type -> Type
    `appK` Type
    x Type -> Type -> Type
    `appK` Type
    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 :: Name -> Q (Maybe Fixity)
    reifyFixityCompat Name
    n = Q (Maybe Fixity) -> Q (Maybe Fixity) -> Q (Maybe Fixity)
    forall a. Q a -> Q a -> Q a
    recover (Maybe Fixity -> Q (Maybe Fixity)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Fixity
    forall a. Maybe a
    Nothing) ((Maybe Fixity -> Maybe Fixity -> Maybe Fixity
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` Fixity -> Maybe Fixity
    forall a. a -> Maybe a
    Just Fixity
    defaultFixity) (Maybe Fixity -> Maybe Fixity)
    -> Q (Maybe Fixity) -> Q (Maybe Fixity)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Q (Maybe Fixity)
    reifyFixity Name
    n)

    -- | Call 'reify' and return @'Just' info@ if successful or 'Nothing' if
    -- reification failed.
    reifyMaybe :: Name -> Q (Maybe Info)
    reifyMaybe :: Name -> Q (Maybe Info)
    reifyMaybe Name
    n = Maybe Info -> Q (Maybe Info)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Info
    forall a. Maybe a
    Nothing Q (Maybe Info) -> Q (Maybe Info) -> Q (Maybe Info)
    forall a. Q a -> Q a -> Q a
    `recover` (Info -> Maybe Info) -> Q Info -> Q (Maybe Info)
    forall a b. (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Info -> Maybe Info
    forall a. a -> Maybe a
    Just (Name -> Q Info
    reify Name
    n)