    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE RecordWildCards #-}
    {-# LANGUAGE TupleSections #-}

    -- | Utilities for reifying simplified datatype info. It omits details
    -- that aren't usually relevant to generating instances that work with
    -- the datatype. This makes it easier to use TH to derive instances.
    --
    -- The \"Simple\" in the module name refers to the simplicity of the
    -- datatypes, not the module itself, which exports quite a few things
    -- which are useful in some circumstance or another. I anticipate that
    -- the most common uses of this will be the following APIs:
    --
    -- * Getting info about a @data@ or @newtype@ declaration, via
    --   'DataType', 'reifyDataType', and 'DataCon'. This is useful for
    --   writing something which generates declarations based on a datatype,
    --   one of the most common uses of Template Haskell.
    --
    -- * Getting nicely structured info about a named type. See 'TypeInfo'
    --   and 'reifyType'. This does not yet support reifying typeclasses,
    --   primitive type constructors, or type variables ('TyVarI').
    --
    -- Currently, this module supports reifying simplified versions of the
    -- following 'Info' constructors:
    --
    -- * 'TyConI' with 'DataD' and 'NewtypeD' (becomes a 'DataType' value)
    --
    -- * 'FamilyI' becomes a 'DataFamily' or 'TypeFamily' value.
    --
    -- * 'DataConI' becomes a 'DataCon' value.
    --
    -- In the future it will hopefully also have support for the remaining
    -- 'Info' constructors, 'ClassI', 'ClassOpI', 'PrimTyConI', 'VarI', and
    -- 'TyVarI'.
    module TH.ReifySimple
        (
        -- * Reifying simplified type info
          TypeInfo, reifyType, infoToType
        , reifyTypeNoDataKinds, infoToTypeNoDataKinds
        -- * Reifying simplified info for specific declaration varieties
        -- ** Datatype info
        , DataType(..), reifyDataType, infoToDataType
        -- ** Data constructor info
        , DataCon(..), reifyDataCon, infoToDataCon, typeToDataCon
        -- ** Data family info
        , DataFamily(..), DataInst(..), reifyDataFamily, infoToDataFamily
        -- ** Type family info
        , TypeFamily(..), TypeInst(..), reifyTypeFamily, infoToTypeFamily
        -- * Other utilities
        , conToDataCons
        , reifyDataTypeSubstituted
        ) where

    import           Control.Applicative
    import           Data.Data (Data, gmapT)
    import           Data.Generics.Aliases (extT)
    import qualified Data.Map as M
    import           Data.Typeable (Typeable)
    import           GHC.Generics (Generic)
    import           Language.Haskell.TH
    #if MIN_VERSION_template_haskell(2,16,0)
                                         hiding (reifyType)
    #endif
    import           Language.Haskell.TH.Instances ()
    import           TH.Utilities

    data TypeInfo
        = DataTypeInfo DataType
        | DataFamilyInfo DataFamily
        | TypeFamilyInfo TypeFamily
        | LiftedDataConInfo DataCon

    -- | Reifies a 'Name' as a 'TypeInfo', and calls 'fail' if this doesn't
    -- work. Use 'reify' with 'infoToType' if you want to handle the failure
    -- case more gracefully.
    --
    -- This does not yet support reifying typeclasses, primitive type
    -- constructors, or type variables ('TyVarI').
    reifyType :: Name -> Q TypeInfo
    reifyType :: Name -> Q TypeInfo
    reifyType Name
    name = do
       info <- Name -> Q Info
    reify Name
    name
       mres <- infoToType info
       case mres of
           Just TypeInfo
    res -> TypeInfo -> Q TypeInfo
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeInfo
    res
           Maybe TypeInfo
    Nothing -> String -> Q TypeInfo
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q TypeInfo) -> String -> Q TypeInfo
    forall a b. (a -> b) -> a -> b
    $
               String
    "Expected to reify a data type, data family, or type family. Instead got:\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
               Info -> String
    forall a. Ppr a => a -> String
    pprint Info
    info

    -- | Convert an 'Info' into a 'TypeInfo' if possible, and otherwise
    -- yield 'Nothing'.  Needs to run in 'Q' so that
    infoToType :: Info -> Q (Maybe TypeInfo)
    infoToType :: Info -> Q (Maybe TypeInfo)
    infoToType Info
    info =
        case (Info -> Maybe TypeInfo
    infoToTypeNoDataKinds Info
    info, Info -> Maybe DataCon
    infoToDataCon Info
    info) of
           (Just TypeInfo
    result, Maybe DataCon
    _) -> Maybe TypeInfo -> Q (Maybe TypeInfo)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeInfo -> Maybe TypeInfo
    forall a. a -> Maybe a
    Just TypeInfo
    result)
           (Maybe TypeInfo
    Nothing, Just DataCon
    dc) -> do
    #if MIN_VERSION_template_haskell(2,11,0)
               dataKindsEnabled <- Extension -> Q Bool
    isExtEnabled Extension
    DataKinds
    #else
               reportWarning $
                   "For " ++ pprint (dcName dc) ++
                   ", assuming DataKinds is on, and yielding LiftedDataConInfo."
               let dataKindsEnabled = True
    #endif
               return $ if dataKindsEnabled then Just (LiftedDataConInfo dc) else Nothing
           (Maybe TypeInfo
    Nothing, Maybe DataCon
    Nothing) -> Maybe TypeInfo -> Q (Maybe TypeInfo)
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe TypeInfo
    forall a. Maybe a
    Nothing

    -- | Reifies type info, but instead of yielding a 'LiftedDataConInfo',
    -- will instead yield 'Nothing'.
    reifyTypeNoDataKinds :: Name -> Q (Maybe TypeInfo)
    reifyTypeNoDataKinds :: Name -> Q (Maybe TypeInfo)
    reifyTypeNoDataKinds = (Info -> Maybe TypeInfo) -> Q Info -> Q (Maybe TypeInfo)
    forall a b. (a -> b) -> Q a -> Q b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Info -> Maybe TypeInfo
    infoToTypeNoDataKinds (Q Info -> Q (Maybe TypeInfo))
    -> (Name -> Q Info) -> Name -> Q (Maybe TypeInfo)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> Q Info
    reify

    -- | Convert an 'Info into a 'TypeInfo' if possible. If it's a data
    -- constructor, instead of yielding 'LiftedDataConInfo', it will instead
    -- yield 'Nothing'.
    infoToTypeNoDataKinds :: Info -> Maybe TypeInfo
    infoToTypeNoDataKinds :: Info -> Maybe TypeInfo
    infoToTypeNoDataKinds Info
    info =
       (DataType -> TypeInfo
    DataTypeInfo (DataType -> TypeInfo) -> Maybe DataType -> Maybe TypeInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Info -> Maybe DataType
    infoToDataType Info
    info) Maybe TypeInfo -> Maybe TypeInfo -> Maybe TypeInfo
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
       (DataFamily -> TypeInfo
    DataFamilyInfo (DataFamily -> TypeInfo) -> Maybe DataFamily -> Maybe TypeInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Info -> Maybe DataFamily
    infoToDataFamily Info
    info) Maybe TypeInfo -> Maybe TypeInfo -> Maybe TypeInfo
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
       (TypeFamily -> TypeInfo
    TypeFamilyInfo (TypeFamily -> TypeInfo) -> Maybe TypeFamily -> Maybe TypeInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Info -> Maybe TypeFamily
    infoToTypeFamily Info
    info)

    --------------------------------------------------------------------------------
    -- Reifying specific declaration varieties

    -- | Simplified info about a 'DataD'. Omits deriving, strictness,
    -- kind info, and whether it's @data@ or @newtype@.
    data DataType = DataType
        { DataType -> Name
    dtName :: Name
        , DataType -> [Name]
    dtTvs :: [Name]
        , DataType -> Cxt
    dtCxt :: Cxt
        , DataType -> [DataCon]
    dtCons :: [DataCon]
        } deriving (DataType -> DataType -> Bool
    (DataType -> DataType -> Bool)
    -> (DataType -> DataType -> Bool) -> Eq DataType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DataType -> DataType -> Bool
    == :: DataType -> DataType -> Bool
    $c/= :: DataType -> DataType -> Bool
    /= :: DataType -> DataType -> Bool
    Eq, Int -> DataType -> String -> String
    [DataType] -> String -> String
    DataType -> String
    (Int -> DataType -> String -> String)
    -> (DataType -> String)
    -> ([DataType] -> String -> String)
    -> Show DataType
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> DataType -> String -> String
    showsPrec :: Int -> DataType -> String -> String
    $cshow :: DataType -> String
    show :: DataType -> String
    $cshowList :: [DataType] -> String -> String
    showList :: [DataType] -> String -> String
    Show, Eq DataType
    Eq DataType =>
    (DataType -> DataType -> Ordering)
    -> (DataType -> DataType -> Bool)
    -> (DataType -> DataType -> Bool)
    -> (DataType -> DataType -> Bool)
    -> (DataType -> DataType -> Bool)
    -> (DataType -> DataType -> DataType)
    -> (DataType -> DataType -> DataType)
    -> Ord DataType
    DataType -> DataType -> Bool
    DataType -> DataType -> Ordering
    DataType -> DataType -> DataType
    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 :: DataType -> DataType -> Ordering
    compare :: DataType -> DataType -> Ordering
    $c< :: DataType -> DataType -> Bool
    < :: DataType -> DataType -> Bool
    $c<= :: DataType -> DataType -> Bool
    <= :: DataType -> DataType -> Bool
    $c> :: DataType -> DataType -> Bool
    > :: DataType -> DataType -> Bool
    $c>= :: DataType -> DataType -> Bool
    >= :: DataType -> DataType -> Bool
    $cmax :: DataType -> DataType -> DataType
    max :: DataType -> DataType -> DataType
    $cmin :: DataType -> DataType -> DataType
    min :: DataType -> DataType -> DataType
    Ord, Typeable DataType
    Typeable DataType =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> DataType -> c DataType)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c DataType)
    -> (DataType -> Constr)
    -> (DataType -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c DataType))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataType))
    -> ((forall b. Data b => b -> b) -> DataType -> DataType)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> DataType -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> DataType -> r)
    -> (forall u. (forall d. Data d => d -> u) -> DataType -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> DataType -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> DataType -> m DataType)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DataType -> m DataType)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DataType -> m DataType)
    -> Data DataType
    DataType -> Constr
    DataType -> DataType
    (forall b. Data b => b -> b) -> DataType -> DataType
    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) -> DataType -> u
    forall u. (forall d. Data d => d -> u) -> DataType -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataType -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataType -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataType -> m DataType
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataType -> m DataType
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataType
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataType -> c DataType
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataType)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataType)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataType -> c DataType
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataType -> c DataType
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataType
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataType
    $ctoConstr :: DataType -> Constr
    toConstr :: DataType -> Constr
    $cdataTypeOf :: DataType -> DataType
    dataTypeOf :: DataType -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataType)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataType)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataType)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataType)
    $cgmapT :: (forall b. Data b => b -> b) -> DataType -> DataType
    gmapT :: (forall b. Data b => b -> b) -> DataType -> DataType
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataType -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataType -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataType -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataType -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> DataType -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> DataType -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataType -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataType -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataType -> m DataType
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataType -> m DataType
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataType -> m DataType
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataType -> m DataType
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataType -> m DataType
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataType -> m DataType
    Data, Typeable, (forall x. DataType -> Rep DataType x)
    -> (forall x. Rep DataType x -> DataType) -> Generic DataType
    forall x. Rep DataType x -> DataType
    forall x. DataType -> Rep DataType x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. DataType -> Rep DataType x
    from :: forall x. DataType -> Rep DataType x
    $cto :: forall x. Rep DataType x -> DataType
    to :: forall x. Rep DataType x -> DataType
    Generic)

    -- | Simplified info about a 'Con'. Omits deriving, strictness, and kind
    -- info. This is much nicer than consuming 'Con' directly, because it
    -- unifies all the constructors into one.
    data DataCon = DataCon
        { DataCon -> Name
    dcName :: Name
        , DataCon -> [Name]
    dcTvs :: [Name]
        , DataCon -> Cxt
    dcCxt :: Cxt
        , DataCon -> [(Maybe Name, Type)]
    dcFields :: [(Maybe Name, Type)]
        } deriving (DataCon -> DataCon -> Bool
    (DataCon -> DataCon -> Bool)
    -> (DataCon -> DataCon -> Bool) -> Eq DataCon
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DataCon -> DataCon -> Bool
    == :: DataCon -> DataCon -> Bool
    $c/= :: DataCon -> DataCon -> Bool
    /= :: DataCon -> DataCon -> Bool
    Eq, Int -> DataCon -> String -> String
    [DataCon] -> String -> String
    DataCon -> String
    (Int -> DataCon -> String -> String)
    -> (DataCon -> String)
    -> ([DataCon] -> String -> String)
    -> Show DataCon
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> DataCon -> String -> String
    showsPrec :: Int -> DataCon -> String -> String
    $cshow :: DataCon -> String
    show :: DataCon -> String
    $cshowList :: [DataCon] -> String -> String
    showList :: [DataCon] -> String -> String
    Show, Eq DataCon
    Eq DataCon =>
    (DataCon -> DataCon -> Ordering)
    -> (DataCon -> DataCon -> Bool)
    -> (DataCon -> DataCon -> Bool)
    -> (DataCon -> DataCon -> Bool)
    -> (DataCon -> DataCon -> Bool)
    -> (DataCon -> DataCon -> DataCon)
    -> (DataCon -> DataCon -> DataCon)
    -> Ord DataCon
    DataCon -> DataCon -> Bool
    DataCon -> DataCon -> Ordering
    DataCon -> DataCon -> DataCon
    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 :: DataCon -> DataCon -> Ordering
    compare :: DataCon -> DataCon -> Ordering
    $c< :: DataCon -> DataCon -> Bool
    < :: DataCon -> DataCon -> Bool
    $c<= :: DataCon -> DataCon -> Bool
    <= :: DataCon -> DataCon -> Bool
    $c> :: DataCon -> DataCon -> Bool
    > :: DataCon -> DataCon -> Bool
    $c>= :: DataCon -> DataCon -> Bool
    >= :: DataCon -> DataCon -> Bool
    $cmax :: DataCon -> DataCon -> DataCon
    max :: DataCon -> DataCon -> DataCon
    $cmin :: DataCon -> DataCon -> DataCon
    min :: DataCon -> DataCon -> DataCon
    Ord, Typeable DataCon
    Typeable DataCon =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> DataCon -> c DataCon)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c DataCon)
    -> (DataCon -> Constr)
    -> (DataCon -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c DataCon))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataCon))
    -> ((forall b. Data b => b -> b) -> DataCon -> DataCon)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> DataCon -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> DataCon -> r)
    -> (forall u. (forall d. Data d => d -> u) -> DataCon -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> DataCon -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> DataCon -> m DataCon)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DataCon -> m DataCon)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DataCon -> m DataCon)
    -> Data DataCon
    DataCon -> Constr
    DataCon -> DataType
    (forall b. Data b => b -> b) -> DataCon -> DataCon
    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) -> DataCon -> u
    forall u. (forall d. Data d => d -> u) -> DataCon -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataCon -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataCon -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataCon -> m DataCon
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataCon -> m DataCon
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataCon
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataCon -> c DataCon
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataCon)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataCon)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataCon -> c DataCon
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataCon -> c DataCon
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataCon
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataCon
    $ctoConstr :: DataCon -> Constr
    toConstr :: DataCon -> Constr
    $cdataTypeOf :: DataCon -> DataType
    dataTypeOf :: DataCon -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataCon)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataCon)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataCon)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataCon)
    $cgmapT :: (forall b. Data b => b -> b) -> DataCon -> DataCon
    gmapT :: (forall b. Data b => b -> b) -> DataCon -> DataCon
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataCon -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataCon -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataCon -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataCon -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> DataCon -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> DataCon -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataCon -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataCon -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataCon -> m DataCon
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataCon -> m DataCon
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataCon -> m DataCon
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataCon -> m DataCon
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataCon -> m DataCon
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataCon -> m DataCon
    Data, Typeable, (forall x. DataCon -> Rep DataCon x)
    -> (forall x. Rep DataCon x -> DataCon) -> Generic DataCon
    forall x. Rep DataCon x -> DataCon
    forall x. DataCon -> Rep DataCon x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. DataCon -> Rep DataCon x
    from :: forall x. DataCon -> Rep DataCon x
    $cto :: forall x. Rep DataCon x -> DataCon
    to :: forall x. Rep DataCon x -> DataCon
    Generic)

    -- | Simplified info about a data family. Omits deriving, strictness, and
    -- kind info.
    data DataFamily = DataFamily
        { DataFamily -> Name
    dfName :: Name
        , DataFamily -> [Name]
    dfTvs :: [Name]
        , DataFamily -> [DataInst]
    dfInsts :: [DataInst]
        } deriving (DataFamily -> DataFamily -> Bool
    (DataFamily -> DataFamily -> Bool)
    -> (DataFamily -> DataFamily -> Bool) -> Eq DataFamily
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DataFamily -> DataFamily -> Bool
    == :: DataFamily -> DataFamily -> Bool
    $c/= :: DataFamily -> DataFamily -> Bool
    /= :: DataFamily -> DataFamily -> Bool
    Eq, Int -> DataFamily -> String -> String
    [DataFamily] -> String -> String
    DataFamily -> String
    (Int -> DataFamily -> String -> String)
    -> (DataFamily -> String)
    -> ([DataFamily] -> String -> String)
    -> Show DataFamily
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> DataFamily -> String -> String
    showsPrec :: Int -> DataFamily -> String -> String
    $cshow :: DataFamily -> String
    show :: DataFamily -> String
    $cshowList :: [DataFamily] -> String -> String
    showList :: [DataFamily] -> String -> String
    Show, Eq DataFamily
    Eq DataFamily =>
    (DataFamily -> DataFamily -> Ordering)
    -> (DataFamily -> DataFamily -> Bool)
    -> (DataFamily -> DataFamily -> Bool)
    -> (DataFamily -> DataFamily -> Bool)
    -> (DataFamily -> DataFamily -> Bool)
    -> (DataFamily -> DataFamily -> DataFamily)
    -> (DataFamily -> DataFamily -> DataFamily)
    -> Ord DataFamily
    DataFamily -> DataFamily -> Bool
    DataFamily -> DataFamily -> Ordering
    DataFamily -> DataFamily -> DataFamily
    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 :: DataFamily -> DataFamily -> Ordering
    compare :: DataFamily -> DataFamily -> Ordering
    $c< :: DataFamily -> DataFamily -> Bool
    < :: DataFamily -> DataFamily -> Bool
    $c<= :: DataFamily -> DataFamily -> Bool
    <= :: DataFamily -> DataFamily -> Bool
    $c> :: DataFamily -> DataFamily -> Bool
    > :: DataFamily -> DataFamily -> Bool
    $c>= :: DataFamily -> DataFamily -> Bool
    >= :: DataFamily -> DataFamily -> Bool
    $cmax :: DataFamily -> DataFamily -> DataFamily
    max :: DataFamily -> DataFamily -> DataFamily
    $cmin :: DataFamily -> DataFamily -> DataFamily
    min :: DataFamily -> DataFamily -> DataFamily
    Ord, Typeable DataFamily
    Typeable DataFamily =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> DataFamily -> c DataFamily)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c DataFamily)
    -> (DataFamily -> Constr)
    -> (DataFamily -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c DataFamily))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c DataFamily))
    -> ((forall b. Data b => b -> b) -> DataFamily -> DataFamily)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> DataFamily -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> DataFamily -> r)
    -> (forall u. (forall d. Data d => d -> u) -> DataFamily -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> DataFamily -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily)
    -> Data DataFamily
    DataFamily -> Constr
    DataFamily -> DataType
    (forall b. Data b => b -> b) -> DataFamily -> DataFamily
    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) -> DataFamily -> u
    forall u. (forall d. Data d => d -> u) -> DataFamily -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataFamily -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataFamily -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataFamily
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataFamily -> c DataFamily
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataFamily)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataFamily)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataFamily -> c DataFamily
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataFamily -> c DataFamily
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataFamily
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataFamily
    $ctoConstr :: DataFamily -> Constr
    toConstr :: DataFamily -> Constr
    $cdataTypeOf :: DataFamily -> DataType
    dataTypeOf :: DataFamily -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataFamily)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataFamily)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataFamily)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataFamily)
    $cgmapT :: (forall b. Data b => b -> b) -> DataFamily -> DataFamily
    gmapT :: (forall b. Data b => b -> b) -> DataFamily -> DataFamily
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataFamily -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataFamily -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataFamily -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataFamily -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> DataFamily -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> DataFamily -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataFamily -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataFamily -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataFamily -> m DataFamily
    Data, Typeable, (forall x. DataFamily -> Rep DataFamily x)
    -> (forall x. Rep DataFamily x -> DataFamily) -> Generic DataFamily
    forall x. Rep DataFamily x -> DataFamily
    forall x. DataFamily -> Rep DataFamily x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. DataFamily -> Rep DataFamily x
    from :: forall x. DataFamily -> Rep DataFamily x
    $cto :: forall x. Rep DataFamily x -> DataFamily
    to :: forall x. Rep DataFamily x -> DataFamily
    Generic)

    -- | Simplified info about a data family instance. Omits deriving,
    -- strictness, and kind info.
    data DataInst = DataInst
        { DataInst -> Name
    diName :: Name
        , DataInst -> Cxt
    diCxt :: Cxt
        , DataInst -> Cxt
    diParams :: [Type]
        , DataInst -> [DataCon]
    diCons :: [DataCon]
        } deriving (DataInst -> DataInst -> Bool
    (DataInst -> DataInst -> Bool)
    -> (DataInst -> DataInst -> Bool) -> Eq DataInst
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DataInst -> DataInst -> Bool
    == :: DataInst -> DataInst -> Bool
    $c/= :: DataInst -> DataInst -> Bool
    /= :: DataInst -> DataInst -> Bool
    Eq, Int -> DataInst -> String -> String
    [DataInst] -> String -> String
    DataInst -> String
    (Int -> DataInst -> String -> String)
    -> (DataInst -> String)
    -> ([DataInst] -> String -> String)
    -> Show DataInst
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> DataInst -> String -> String
    showsPrec :: Int -> DataInst -> String -> String
    $cshow :: DataInst -> String
    show :: DataInst -> String
    $cshowList :: [DataInst] -> String -> String
    showList :: [DataInst] -> String -> String
    Show, Eq DataInst
    Eq DataInst =>
    (DataInst -> DataInst -> Ordering)
    -> (DataInst -> DataInst -> Bool)
    -> (DataInst -> DataInst -> Bool)
    -> (DataInst -> DataInst -> Bool)
    -> (DataInst -> DataInst -> Bool)
    -> (DataInst -> DataInst -> DataInst)
    -> (DataInst -> DataInst -> DataInst)
    -> Ord DataInst
    DataInst -> DataInst -> Bool
    DataInst -> DataInst -> Ordering
    DataInst -> DataInst -> DataInst
    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 :: DataInst -> DataInst -> Ordering
    compare :: DataInst -> DataInst -> Ordering
    $c< :: DataInst -> DataInst -> Bool
    < :: DataInst -> DataInst -> Bool
    $c<= :: DataInst -> DataInst -> Bool
    <= :: DataInst -> DataInst -> Bool
    $c> :: DataInst -> DataInst -> Bool
    > :: DataInst -> DataInst -> Bool
    $c>= :: DataInst -> DataInst -> Bool
    >= :: DataInst -> DataInst -> Bool
    $cmax :: DataInst -> DataInst -> DataInst
    max :: DataInst -> DataInst -> DataInst
    $cmin :: DataInst -> DataInst -> DataInst
    min :: DataInst -> DataInst -> DataInst
    Ord, Typeable DataInst
    Typeable DataInst =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> DataInst -> c DataInst)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c DataInst)
    -> (DataInst -> Constr)
    -> (DataInst -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c DataInst))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataInst))
    -> ((forall b. Data b => b -> b) -> DataInst -> DataInst)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> DataInst -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> DataInst -> r)
    -> (forall u. (forall d. Data d => d -> u) -> DataInst -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> DataInst -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> DataInst -> m DataInst)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DataInst -> m DataInst)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> DataInst -> m DataInst)
    -> Data DataInst
    DataInst -> Constr
    DataInst -> DataType
    (forall b. Data b => b -> b) -> DataInst -> DataInst
    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) -> DataInst -> u
    forall u. (forall d. Data d => d -> u) -> DataInst -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataInst -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataInst -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataInst -> m DataInst
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataInst -> m DataInst
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataInst
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataInst -> c DataInst
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataInst)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataInst)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataInst -> c DataInst
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DataInst -> c DataInst
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataInst
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataInst
    $ctoConstr :: DataInst -> Constr
    toConstr :: DataInst -> Constr
    $cdataTypeOf :: DataInst -> DataType
    dataTypeOf :: DataInst -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataInst)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataInst)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataInst)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataInst)
    $cgmapT :: (forall b. Data b => b -> b) -> DataInst -> DataInst
    gmapT :: (forall b. Data b => b -> b) -> DataInst -> DataInst
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataInst -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataInst -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataInst -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataInst -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> DataInst -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> DataInst -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataInst -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataInst -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataInst -> m DataInst
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataInst -> m DataInst
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataInst -> m DataInst
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataInst -> m DataInst
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataInst -> m DataInst
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataInst -> m DataInst
    Data, Typeable, (forall x. DataInst -> Rep DataInst x)
    -> (forall x. Rep DataInst x -> DataInst) -> Generic DataInst
    forall x. Rep DataInst x -> DataInst
    forall x. DataInst -> Rep DataInst x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. DataInst -> Rep DataInst x
    from :: forall x. DataInst -> Rep DataInst x
    $cto :: forall x. Rep DataInst x -> DataInst
    to :: forall x. Rep DataInst x -> DataInst
    Generic)

    -- | Simplified info about a type family. Omits kind info and injectivity
    -- info.
    data TypeFamily = TypeFamily
        { TypeFamily -> Name
    tfName :: Name
        , TypeFamily -> [Name]
    tfTvs :: [Name]
        , TypeFamily -> [TypeInst]
    tfInsts :: [TypeInst]
        } deriving (TypeFamily -> TypeFamily -> Bool
    (TypeFamily -> TypeFamily -> Bool)
    -> (TypeFamily -> TypeFamily -> Bool) -> Eq TypeFamily
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: TypeFamily -> TypeFamily -> Bool
    == :: TypeFamily -> TypeFamily -> Bool
    $c/= :: TypeFamily -> TypeFamily -> Bool
    /= :: TypeFamily -> TypeFamily -> Bool
    Eq, Int -> TypeFamily -> String -> String
    [TypeFamily] -> String -> String
    TypeFamily -> String
    (Int -> TypeFamily -> String -> String)
    -> (TypeFamily -> String)
    -> ([TypeFamily] -> String -> String)
    -> Show TypeFamily
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> TypeFamily -> String -> String
    showsPrec :: Int -> TypeFamily -> String -> String
    $cshow :: TypeFamily -> String
    show :: TypeFamily -> String
    $cshowList :: [TypeFamily] -> String -> String
    showList :: [TypeFamily] -> String -> String
    Show, Eq TypeFamily
    Eq TypeFamily =>
    (TypeFamily -> TypeFamily -> Ordering)
    -> (TypeFamily -> TypeFamily -> Bool)
    -> (TypeFamily -> TypeFamily -> Bool)
    -> (TypeFamily -> TypeFamily -> Bool)
    -> (TypeFamily -> TypeFamily -> Bool)
    -> (TypeFamily -> TypeFamily -> TypeFamily)
    -> (TypeFamily -> TypeFamily -> TypeFamily)
    -> Ord TypeFamily
    TypeFamily -> TypeFamily -> Bool
    TypeFamily -> TypeFamily -> Ordering
    TypeFamily -> TypeFamily -> TypeFamily
    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 :: TypeFamily -> TypeFamily -> Ordering
    compare :: TypeFamily -> TypeFamily -> Ordering
    $c< :: TypeFamily -> TypeFamily -> Bool
    < :: TypeFamily -> TypeFamily -> Bool
    $c<= :: TypeFamily -> TypeFamily -> Bool
    <= :: TypeFamily -> TypeFamily -> Bool
    $c> :: TypeFamily -> TypeFamily -> Bool
    > :: TypeFamily -> TypeFamily -> Bool
    $c>= :: TypeFamily -> TypeFamily -> Bool
    >= :: TypeFamily -> TypeFamily -> Bool
    $cmax :: TypeFamily -> TypeFamily -> TypeFamily
    max :: TypeFamily -> TypeFamily -> TypeFamily
    $cmin :: TypeFamily -> TypeFamily -> TypeFamily
    min :: TypeFamily -> TypeFamily -> TypeFamily
    Ord, Typeable TypeFamily
    Typeable TypeFamily =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> TypeFamily -> c TypeFamily)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c TypeFamily)
    -> (TypeFamily -> Constr)
    -> (TypeFamily -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c TypeFamily))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c TypeFamily))
    -> ((forall b. Data b => b -> b) -> TypeFamily -> TypeFamily)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> TypeFamily -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> TypeFamily -> r)
    -> (forall u. (forall d. Data d => d -> u) -> TypeFamily -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> TypeFamily -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily)
    -> Data TypeFamily
    TypeFamily -> Constr
    TypeFamily -> DataType
    (forall b. Data b => b -> b) -> TypeFamily -> TypeFamily
    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) -> TypeFamily -> u
    forall u. (forall d. Data d => d -> u) -> TypeFamily -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeFamily -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeFamily -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TypeFamily
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TypeFamily -> c TypeFamily
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TypeFamily)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeFamily)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TypeFamily -> c TypeFamily
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TypeFamily -> c TypeFamily
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TypeFamily
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TypeFamily
    $ctoConstr :: TypeFamily -> Constr
    toConstr :: TypeFamily -> Constr
    $cdataTypeOf :: TypeFamily -> DataType
    dataTypeOf :: TypeFamily -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TypeFamily)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TypeFamily)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeFamily)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeFamily)
    $cgmapT :: (forall b. Data b => b -> b) -> TypeFamily -> TypeFamily
    gmapT :: (forall b. Data b => b -> b) -> TypeFamily -> TypeFamily
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeFamily -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeFamily -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeFamily -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeFamily -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> TypeFamily -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> TypeFamily -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TypeFamily -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TypeFamily -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeFamily -> m TypeFamily
    Data, Typeable, (forall x. TypeFamily -> Rep TypeFamily x)
    -> (forall x. Rep TypeFamily x -> TypeFamily) -> Generic TypeFamily
    forall x. Rep TypeFamily x -> TypeFamily
    forall x. TypeFamily -> Rep TypeFamily x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. TypeFamily -> Rep TypeFamily x
    from :: forall x. TypeFamily -> Rep TypeFamily x
    $cto :: forall x. Rep TypeFamily x -> TypeFamily
    to :: forall x. Rep TypeFamily x -> TypeFamily
    Generic)

    -- | Simplified info about a type family instance. Omits nothing.
    data TypeInst = TypeInst
        { TypeInst -> Name
    tiName :: Name
        , TypeInst -> Cxt
    tiParams :: [Type]
        , TypeInst -> Type
    tiType :: Type
        } deriving (TypeInst -> TypeInst -> Bool
    (TypeInst -> TypeInst -> Bool)
    -> (TypeInst -> TypeInst -> Bool) -> Eq TypeInst
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: TypeInst -> TypeInst -> Bool
    == :: TypeInst -> TypeInst -> Bool
    $c/= :: TypeInst -> TypeInst -> Bool
    /= :: TypeInst -> TypeInst -> Bool
    Eq, Int -> TypeInst -> String -> String
    [TypeInst] -> String -> String
    TypeInst -> String
    (Int -> TypeInst -> String -> String)
    -> (TypeInst -> String)
    -> ([TypeInst] -> String -> String)
    -> Show TypeInst
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> TypeInst -> String -> String
    showsPrec :: Int -> TypeInst -> String -> String
    $cshow :: TypeInst -> String
    show :: TypeInst -> String
    $cshowList :: [TypeInst] -> String -> String
    showList :: [TypeInst] -> String -> String
    Show, Eq TypeInst
    Eq TypeInst =>
    (TypeInst -> TypeInst -> Ordering)
    -> (TypeInst -> TypeInst -> Bool)
    -> (TypeInst -> TypeInst -> Bool)
    -> (TypeInst -> TypeInst -> Bool)
    -> (TypeInst -> TypeInst -> Bool)
    -> (TypeInst -> TypeInst -> TypeInst)
    -> (TypeInst -> TypeInst -> TypeInst)
    -> Ord TypeInst
    TypeInst -> TypeInst -> Bool
    TypeInst -> TypeInst -> Ordering
    TypeInst -> TypeInst -> TypeInst
    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 :: TypeInst -> TypeInst -> Ordering
    compare :: TypeInst -> TypeInst -> Ordering
    $c< :: TypeInst -> TypeInst -> Bool
    < :: TypeInst -> TypeInst -> Bool
    $c<= :: TypeInst -> TypeInst -> Bool
    <= :: TypeInst -> TypeInst -> Bool
    $c> :: TypeInst -> TypeInst -> Bool
    > :: TypeInst -> TypeInst -> Bool
    $c>= :: TypeInst -> TypeInst -> Bool
    >= :: TypeInst -> TypeInst -> Bool
    $cmax :: TypeInst -> TypeInst -> TypeInst
    max :: TypeInst -> TypeInst -> TypeInst
    $cmin :: TypeInst -> TypeInst -> TypeInst
    min :: TypeInst -> TypeInst -> TypeInst
    Ord, Typeable TypeInst
    Typeable TypeInst =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> TypeInst -> c TypeInst)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c TypeInst)
    -> (TypeInst -> Constr)
    -> (TypeInst -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c TypeInst))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeInst))
    -> ((forall b. Data b => b -> b) -> TypeInst -> TypeInst)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> TypeInst -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> TypeInst -> r)
    -> (forall u. (forall d. Data d => d -> u) -> TypeInst -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> TypeInst -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst)
    -> Data TypeInst
    TypeInst -> Constr
    TypeInst -> DataType
    (forall b. Data b => b -> b) -> TypeInst -> TypeInst
    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) -> TypeInst -> u
    forall u. (forall d. Data d => d -> u) -> TypeInst -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeInst -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeInst -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TypeInst
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TypeInst -> c TypeInst
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TypeInst)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeInst)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TypeInst -> c TypeInst
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TypeInst -> c TypeInst
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TypeInst
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TypeInst
    $ctoConstr :: TypeInst -> Constr
    toConstr :: TypeInst -> Constr
    $cdataTypeOf :: TypeInst -> DataType
    dataTypeOf :: TypeInst -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TypeInst)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TypeInst)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeInst)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeInst)
    $cgmapT :: (forall b. Data b => b -> b) -> TypeInst -> TypeInst
    gmapT :: (forall b. Data b => b -> b) -> TypeInst -> TypeInst
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeInst -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeInst -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeInst -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeInst -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> TypeInst -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> TypeInst -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TypeInst -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TypeInst -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeInst -> m TypeInst
    Data, Typeable, (forall x. TypeInst -> Rep TypeInst x)
    -> (forall x. Rep TypeInst x -> TypeInst) -> Generic TypeInst
    forall x. Rep TypeInst x -> TypeInst
    forall x. TypeInst -> Rep TypeInst x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. TypeInst -> Rep TypeInst x
    from :: forall x. TypeInst -> Rep TypeInst x
    $cto :: forall x. Rep TypeInst x -> TypeInst
    to :: forall x. Rep TypeInst x -> TypeInst
    Generic)

    -- | Reify the given data or newtype declaration, and yields its
    -- 'DataType' representation.
    reifyDataType :: Name -> Q DataType
    reifyDataType :: Name -> Q DataType
    reifyDataType Name
    name = do
        info <- Name -> Q Info
    reify Name
    name
        case infoToDataType info of
            Maybe DataType
    Nothing -> String -> Q DataType
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q DataType) -> String -> Q DataType
    forall a b. (a -> b) -> a -> b
    $ String
    "Expected to reify a datatype. Instead got:\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Info -> String
    forall a. Ppr a => a -> String
    pprint Info
    info
            Just DataType
    x -> DataType -> Q DataType
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return DataType
    x

    -- | Reify the given data constructor.
    reifyDataCon :: Name -> Q DataCon
    reifyDataCon :: Name -> Q DataCon
    reifyDataCon Name
    name = do
        info <- Name -> Q Info
    reify Name
    name
        case infoToDataCon info of
            Maybe DataCon
    Nothing -> String -> Q DataCon
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q DataCon) -> String -> Q DataCon
    forall a b. (a -> b) -> a -> b
    $ String
    "Expected to reify a constructor. Instead got:\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Info -> String
    forall a. Ppr a => a -> String
    pprint Info
    info
            Just DataCon
    x -> DataCon -> Q DataCon
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return DataCon
    x

    -- | Reify the given data family, and yield its 'DataFamily'
    -- representation.
    reifyDataFamily :: Name -> Q DataFamily
    reifyDataFamily :: Name -> Q DataFamily
    reifyDataFamily Name
    name = do
        info <- Name -> Q Info
    reify Name
    name
        case infoToDataFamily info of
            Maybe DataFamily
    Nothing -> String -> Q DataFamily
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q DataFamily) -> String -> Q DataFamily
    forall a b. (a -> b) -> a -> b
    $ String
    "Expected to reify a data family. Instead got:\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Info -> String
    forall a. Ppr a => a -> String
    pprint Info
    info
            Just DataFamily
    x -> DataFamily -> Q DataFamily
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return DataFamily
    x

    -- | Reify the given type family instance declaration, and yields its
    -- 'TypeInst' representation.
    reifyTypeFamily :: Name -> Q TypeFamily
    reifyTypeFamily :: Name -> Q TypeFamily
    reifyTypeFamily Name
    name = do
        info <- Name -> Q Info
    reify Name
    name
        case infoToTypeFamily info of
            Maybe TypeFamily
    Nothing -> String -> Q TypeFamily
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q TypeFamily) -> String -> Q TypeFamily
    forall a b. (a -> b) -> a -> b
    $ String
    "Expected to reify a type family. Instead got:\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Info -> String
    forall a. Ppr a => a -> String
    pprint Info
    info
            Just TypeFamily
    x -> TypeFamily -> Q TypeFamily
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeFamily
    x

    infoToDataType :: Info -> Maybe DataType
    infoToDataType :: Info -> Maybe DataType
    infoToDataType Info
    info = case Info
    info of
    #if MIN_VERSION_template_haskell(2,11,0)
        TyConI (DataD Cxt
    preds Name
    name [TyVarBndr BndrVis]
    tvs Maybe Type
    _kind [Con]
    cons [DerivClause]
    _deriving) ->
    #else
        TyConI (DataD preds name tvs cons _deriving) ->
    #endif
            DataType -> Maybe DataType
    forall a. a -> Maybe a
    Just (DataType -> Maybe DataType) -> DataType -> Maybe DataType
    forall a b. (a -> b) -> a -> b
    $ Name -> [Name] -> Cxt -> [DataCon] -> DataType
    DataType Name
    name ((TyVarBndr BndrVis -> Name) -> [TyVarBndr BndrVis] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr BndrVis -> Name
    forall flag. TyVarBndr_ flag -> Name
    tyVarBndrName [TyVarBndr BndrVis]
    tvs) Cxt
    preds ((Con -> [DataCon]) -> [Con] -> [DataCon]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Con -> [DataCon]
    conToDataCons [Con]
    cons)
    #if MIN_VERSION_template_haskell(2,11,0)
        TyConI (NewtypeD Cxt
    preds Name
    name [TyVarBndr BndrVis]
    tvs Maybe Type
    _kind Con
    con [DerivClause]
    _deriving) ->
    #else
        TyConI (NewtypeD preds name tvs con _deriving) ->
    #endif
            DataType -> Maybe DataType
    forall a. a -> Maybe a
    Just (DataType -> Maybe DataType) -> DataType -> Maybe DataType
    forall a b. (a -> b) -> a -> b
    $ Name -> [Name] -> Cxt -> [DataCon] -> DataType
    DataType Name
    name ((TyVarBndr BndrVis -> Name) -> [TyVarBndr BndrVis] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr BndrVis -> Name
    forall flag. TyVarBndr_ flag -> Name
    tyVarBndrName [TyVarBndr BndrVis]
    tvs) Cxt
    preds (Con -> [DataCon]
    conToDataCons Con
    con)
        Info
    _ -> Maybe DataType
    forall a. Maybe a
    Nothing

    infoToDataFamily :: Info -> Maybe DataFamily
    infoToDataFamily :: Info -> Maybe DataFamily
    infoToDataFamily Info
    info = case Info
    info of
    #if MIN_VERSION_template_haskell(2,11,0)
        FamilyI (DataFamilyD Name
    name [TyVarBndr BndrVis]
    tvs Maybe Type
    _kind) [Dec]
    insts ->
    #else
        FamilyI (FamilyD DataFam name tvs _kind) insts ->
    #endif
            DataFamily -> Maybe DataFamily
    forall a. a -> Maybe a
    Just (DataFamily -> Maybe DataFamily) -> DataFamily -> Maybe DataFamily
    forall a b. (a -> b) -> a -> b
    $ Name -> [Name] -> [DataInst] -> DataFamily
    DataFamily Name
    name ((TyVarBndr BndrVis -> Name) -> [TyVarBndr BndrVis] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr BndrVis -> Name
    forall flag. TyVarBndr_ flag -> Name
    tyVarBndrName [TyVarBndr BndrVis]
    tvs) ((Dec -> DataInst) -> [Dec] -> [DataInst]
    forall a b. (a -> b) -> [a] -> [b]
    map Dec -> DataInst
    go [Dec]
    insts)
        Info
    _ -> Maybe DataFamily
    forall a. Maybe a
    Nothing
      where
    #if MIN_VERSION_template_haskell(2,15,0)
        go :: Dec -> DataInst
    go (NewtypeInstD Cxt
    preds Maybe [TyVarBndr ()]
    _ Type
    lhs Maybe Type
    _kind Con
    con [DerivClause]
    _deriving)
          | ConT Name
    name:Cxt
    params <- Type -> Cxt
    unAppsT Type
    lhs
    #elif MIN_VERSION_template_haskell(2,11,0)
        go (NewtypeInstD preds name params _kind con _deriving)
    #else
        go (NewtypeInstD preds name params       con _deriving)
    #endif
          = Name -> Cxt -> Cxt -> [DataCon] -> DataInst
    DataInst Name
    name Cxt
    preds Cxt
    params (Con -> [DataCon]
    conToDataCons Con
    con)
    #if MIN_VERSION_template_haskell(2,15,0)
        go (DataInstD Cxt
    preds Maybe [TyVarBndr ()]
    _ Type
    lhs Maybe Type
    _kind [Con]
    cons [DerivClause]
    _deriving)
          | ConT Name
    name:Cxt
    params <- Type -> Cxt
    unAppsT Type
    lhs
    #elif MIN_VERSION_template_haskell(2,11,0)
        go (DataInstD preds name params _kind cons _deriving)
    #else
        go (DataInstD preds name params       cons _deriving)
    #endif
          = Name -> Cxt -> Cxt -> [DataCon] -> DataInst
    DataInst Name
    name Cxt
    preds Cxt
    params ((Con -> [DataCon]) -> [Con] -> [DataCon]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Con -> [DataCon]
    conToDataCons [Con]
    cons)
        go Dec
    info' = String -> DataInst
    forall a. HasCallStack => String -> a
    error (String -> DataInst) -> String -> DataInst
    forall a b. (a -> b) -> a -> b
    $
            String
    "Unexpected instance in FamilyI in infoToDataInsts:\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Dec -> String
    forall a. Ppr a => a -> String
    pprint Dec
    info'

    infoToTypeFamily :: Info -> Maybe TypeFamily
    infoToTypeFamily :: Info -> Maybe TypeFamily
    infoToTypeFamily Info
    info = case Info
    info of
    #if MIN_VERSION_template_haskell(2,11,0)
        FamilyI (ClosedTypeFamilyD (TypeFamilyHead Name
    name [TyVarBndr BndrVis]
    tvs FamilyResultSig
    _result Maybe InjectivityAnn
    _injectivity) [TySynEqn]
    eqns) [Dec]
    _ ->
            TypeFamily -> Maybe TypeFamily
    forall a. a -> Maybe a
    Just (TypeFamily -> Maybe TypeFamily) -> TypeFamily -> Maybe TypeFamily
    forall a b. (a -> b) -> a -> b
    $ Name -> [Name] -> [TypeInst] -> TypeFamily
    TypeFamily Name
    name ((TyVarBndr BndrVis -> Name) -> [TyVarBndr BndrVis] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr BndrVis -> Name
    forall flag. TyVarBndr_ flag -> Name
    tyVarBndrName [TyVarBndr BndrVis]
    tvs) ([TypeInst] -> TypeFamily) -> [TypeInst] -> TypeFamily
    forall a b. (a -> b) -> a -> b
    $ (TySynEqn -> TypeInst) -> [TySynEqn] -> [TypeInst]
    forall a b. (a -> b) -> [a] -> [b]
    map (Name -> TySynEqn -> TypeInst
    goEqn Name
    name) [TySynEqn]
    eqns
        FamilyI (OpenTypeFamilyD (TypeFamilyHead Name
    name [TyVarBndr BndrVis]
    tvs FamilyResultSig
    _result Maybe InjectivityAnn
    _injectivity)) [Dec]
    insts ->
            TypeFamily -> Maybe TypeFamily
    forall a. a -> Maybe a
    Just (TypeFamily -> Maybe TypeFamily) -> TypeFamily -> Maybe TypeFamily
    forall a b. (a -> b) -> a -> b
    $ Name -> [Name] -> [TypeInst] -> TypeFamily
    TypeFamily Name
    name ((TyVarBndr BndrVis -> Name) -> [TyVarBndr BndrVis] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr BndrVis -> Name
    forall flag. TyVarBndr_ flag -> Name
    tyVarBndrName [TyVarBndr BndrVis]
    tvs) ([TypeInst] -> TypeFamily) -> [TypeInst] -> TypeFamily
    forall a b. (a -> b) -> a -> b
    $ (Dec -> TypeInst) -> [Dec] -> [TypeInst]
    forall a b. (a -> b) -> [a] -> [b]
    map (Name -> Dec -> TypeInst
    goInst Name
    name) [Dec]
    insts
    #else
        FamilyI (ClosedTypeFamilyD name tvs _kind eqns) [] ->
            Just $ TypeFamily name (map tyVarBndrName tvs) $ map (goEqn name) eqns
        FamilyI (FamilyD TypeFam name tvs _kind) insts ->
            Just $ TypeFamily name (map tyVarBndrName tvs) $ map (goInst name) insts
    #endif
        Info
    _ -> Maybe TypeFamily
    forall a. Maybe a
    Nothing
      where
    #if MIN_VERSION_template_haskell(2,15,0)
        toParams :: Cxt -> Type -> Cxt
    toParams Cxt
    ps (AppT Type
    ty Type
    p) = Cxt -> Type -> Cxt
    toParams (Type
    p Type -> Cxt -> Cxt
    forall a. a -> [a] -> [a]
    : Cxt
    ps) Type
    ty
        toParams Cxt
    ps (AppKindT Type
    ty Type
    _) = Cxt -> Type -> Cxt
    toParams Cxt
    ps Type
    ty
        toParams Cxt
    ps Type
    _ = Cxt
    ps
        goEqn :: Name -> TySynEqn -> TypeInst
    goEqn Name
    name (TySynEqn Maybe [TyVarBndr ()]
    _ Type
    lty Type
    rty) = Name -> Cxt -> Type -> TypeInst
    TypeInst Name
    name (Cxt -> Type -> Cxt
    toParams [] Type
    lty) Type
    rty
        goInst :: Name -> Dec -> TypeInst
    goInst Name
    name (TySynInstD TySynEqn
    eqn) = Name -> TySynEqn -> TypeInst
    goEqn Name
    name TySynEqn
    eqn
        goInst Name
    _ Dec
    info' = String -> TypeInst
    forall a. HasCallStack => String -> a
    error (String -> TypeInst) -> String -> TypeInst
    forall a b. (a -> b) -> a -> b
    $
            String
    "Unexpected instance in FamilyI in infoToTypeInsts:\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Dec -> String
    forall a. Ppr a => a -> String
    pprint Dec
    info'
    #else
        goEqn name (TySynEqn params ty) = TypeInst name params ty
        goInst name (TySynInstD _ eqn) = goEqn name eqn
        goInst _ info' = error $
            "Unexpected instance in FamilyI in infoToTypeInsts:\n" ++ pprint info'
    #endif

    infoToDataCon :: Info -> Maybe DataCon
    infoToDataCon :: Info -> Maybe DataCon
    infoToDataCon Info
    info = case Info
    info of
    #if MIN_VERSION_template_haskell(2,11,0)
        DataConI Name
    name Type
    ty Name
    _parent ->
    #else
        DataConI name ty _parent _fixity ->
    #endif
            DataCon -> Maybe DataCon
    forall a. a -> Maybe a
    Just (Name -> Type -> DataCon
    typeToDataCon Name
    name Type
    ty)
        Info
    _ -> Maybe DataCon
    forall a. Maybe a
    Nothing

    -- | Creates a 'DataCon' given the 'Name' and 'Type' of a
    -- data-constructor.  Note that the result the function type is *not* checked to match the provided 'Name'.
    typeToDataCon :: Name -> Type -> DataCon
    typeToDataCon :: Name -> Type -> DataCon
    typeToDataCon Name
    dcName Type
    ty0 = DataCon {Cxt
    [Name]
    [(Maybe Name, Type)]
    Name
    forall {a}. [(Maybe a, Type)]
    dcName :: Name
    dcTvs :: [Name]
    dcCxt :: Cxt
    dcFields :: [(Maybe Name, Type)]
    dcName :: Name
    dcTvs :: [Name]
    dcCxt :: Cxt
    dcFields :: forall {a}. [(Maybe a, Type)]
    ..}
      where
        ([Name]
    dcTvs, Cxt
    dcCxt, [(Maybe a, Type)]
    dcFields) = case Type
    ty0 of
            ForallT [TyVarBndr Specificity]
    tvs Cxt
    preds Type
    ty -> ((TyVarBndr Specificity -> Name)
    -> [TyVarBndr Specificity] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr Specificity -> Name
    forall flag. TyVarBndr_ flag -> Name
    tyVarBndrName [TyVarBndr Specificity]
    tvs, Cxt
    preds, Type -> [(Maybe a, Type)]
    forall {a}. Type -> [(Maybe a, Type)]
    typeToFields Type
    ty)
            Type
    ty -> ([], [], Type -> [(Maybe a, Type)]
    forall {a}. Type -> [(Maybe a, Type)]
    typeToFields Type
    ty)
        -- TODO: Should we sanity check the result type?
        typeToFields :: Type -> [(Maybe a, Type)]
    typeToFields = [(Maybe a, Type)] -> [(Maybe a, Type)]
    forall a. HasCallStack => [a] -> [a]
    init ([(Maybe a, Type)] -> [(Maybe a, Type)])
    -> (Type -> [(Maybe a, Type)]) -> Type -> [(Maybe a, Type)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Type -> (Maybe a, Type)) -> Cxt -> [(Maybe a, Type)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Maybe a
    forall a. Maybe a
    Nothing, ) (Cxt -> [(Maybe a, Type)])
    -> (Type -> Cxt) -> Type -> [(Maybe a, Type)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Type -> Cxt
    unAppsT

    -- | Convert a 'Con' to a list of 'DataCon'. The result is a list
    -- because 'GadtC' and 'RecGadtC' can define multiple constructors.
    conToDataCons :: Con -> [DataCon]
    conToDataCons :: Con -> [DataCon]
    conToDataCons = \case
        NormalC Name
    name [BangType]
    slots ->
            [Name -> [Name] -> Cxt -> [(Maybe Name, Type)] -> DataCon
    DataCon Name
    name [] [] ((BangType -> (Maybe Name, Type))
    -> [BangType] -> [(Maybe Name, Type)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Bang
    _, Type
    ty) -> (Maybe Name
    forall a. Maybe a
    Nothing, Type
    ty)) [BangType]
    slots)]
        RecC Name
    name [VarBangType]
    fields ->
            [Name -> [Name] -> Cxt -> [(Maybe Name, Type)] -> DataCon
    DataCon Name
    name [] [] ((VarBangType -> (Maybe Name, Type))
    -> [VarBangType] -> [(Maybe Name, Type)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Name
    n, Bang
    _, Type
    ty) -> (Name -> Maybe Name
    forall a. a -> Maybe a
    Just Name
    n, Type
    ty)) [VarBangType]
    fields)]
        InfixC (Bang
    _, Type
    ty1) Name
    name (Bang
    _, Type
    ty2) ->
            [Name -> [Name] -> Cxt -> [(Maybe Name, Type)] -> DataCon
    DataCon Name
    name [] [] [(Maybe Name
    forall a. Maybe a
    Nothing, Type
    ty1), (Maybe Name
    forall a. Maybe a
    Nothing, Type
    ty2)]]
        ForallC [TyVarBndr Specificity]
    tvs Cxt
    preds Con
    con ->
            (DataCon -> DataCon) -> [DataCon] -> [DataCon]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(DataCon Name
    name [Name]
    tvs0 Cxt
    preds0 [(Maybe Name, Type)]
    fields) ->
                Name -> [Name] -> Cxt -> [(Maybe Name, Type)] -> DataCon
    DataCon Name
    name ([Name]
    tvs0 [Name] -> [Name] -> [Name]
    forall a. [a] -> [a] -> [a]
    ++ (TyVarBndr Specificity -> Name)
    -> [TyVarBndr Specificity] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndr Specificity -> Name
    forall flag. TyVarBndr_ flag -> Name
    tyVarBndrName [TyVarBndr Specificity]
    tvs) (Cxt
    preds0 Cxt -> Cxt -> Cxt
    forall a. [a] -> [a] -> [a]
    ++ Cxt
    preds) [(Maybe Name, Type)]
    fields) (Con -> [DataCon]
    conToDataCons Con
    con)
    #if MIN_VERSION_template_haskell(2,11,0)
        GadtC [Name]
    ns [BangType]
    slots Type
    _ ->
            (Name -> DataCon) -> [Name] -> [DataCon]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Name
    dn -> Name -> [Name] -> Cxt -> [(Maybe Name, Type)] -> DataCon
    DataCon Name
    dn [] [] ((BangType -> (Maybe Name, Type))
    -> [BangType] -> [(Maybe Name, Type)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Bang
    _, Type
    ty) -> (Maybe Name
    forall a. Maybe a
    Nothing, Type
    ty)) [BangType]
    slots)) [Name]
    ns
        RecGadtC [Name]
    ns [VarBangType]
    fields Type
    _ ->
            (Name -> DataCon) -> [Name] -> [DataCon]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Name
    dn -> Name -> [Name] -> Cxt -> [(Maybe Name, Type)] -> DataCon
    DataCon Name
    dn [] [] ((VarBangType -> (Maybe Name, Type))
    -> [VarBangType] -> [(Maybe Name, Type)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Name
    fn, Bang
    _, Type
    ty) -> (Name -> Maybe Name
    forall a. a -> Maybe a
    Just Name
    fn, Type
    ty)) [VarBangType]
    fields)) [Name]
    ns
    #endif

    -- | Like 'reifyDataType', but takes a 'Type' instead of just the 'Name'
    -- of the datatype. It expects a normal datatype argument (see
    -- 'typeToNamedCon').
    reifyDataTypeSubstituted :: Type -> Q DataType
    reifyDataTypeSubstituted :: Type -> Q DataType
    reifyDataTypeSubstituted Type
    ty =
        case Type -> Maybe (Name, Cxt)
    typeToNamedCon Type
    ty of
            Maybe (Name, Cxt)
    Nothing -> String -> Q DataType
    forall a. String -> Q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Q DataType) -> String -> Q DataType
    forall a b. (a -> b) -> a -> b
    $ String
    "Expected a datatype, but reifyDataTypeSubstituted was applied to " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Type -> String
    forall a. Ppr a => a -> String
    pprint Type
    ty
            Just (Name
    n, Cxt
    args) -> do
                dt <- Name -> Q DataType
    reifyDataType Name
    n
                let cons' = Map Name Type -> [DataCon] -> [DataCon]
    forall a. Data a => Map Name Type -> a -> a
    substituteTvs ([(Name, Type)] -> Map Name Type
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([Name] -> Cxt -> [(Name, Type)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip (DataType -> [Name]
    dtTvs DataType
    dt) Cxt
    args)) (DataType -> [DataCon]
    dtCons DataType
    dt)
                return (dt { dtCons = cons' })

    -- TODO: add various handy generics based traversals to TH.Utilities

    substituteTvs :: Data a => M.Map Name Type -> a -> a
    substituteTvs :: forall a. Data a => Map Name Type -> a -> a
    substituteTvs Map Name Type
    mp = (Type -> Type) -> a -> a
    forall a. Data a => (Type -> Type) -> a -> a
    transformTypes Type -> Type
    go
      where
        go :: Type -> Type
    go (VarT Name
    name) | Just Type
    ty <- Name -> Map Name Type -> Maybe Type
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup Name
    name Map Name Type
    mp = Type
    ty
        go Type
    ty = (forall b. Data b => b -> b) -> Type -> Type
    forall a. Data a => (forall b. Data b => b -> b) -> a -> a
    gmapT (Map Name Type -> b -> b
    forall a. Data a => Map Name Type -> a -> a
    substituteTvs Map Name Type
    mp) Type
    ty

    transformTypes :: Data a => (Type -> Type) -> a -> a
    transformTypes :: forall a. Data a => (Type -> Type) -> a -> a
    transformTypes Type -> Type
    f = (forall b. Data b => b -> b) -> a -> a
    forall a. Data a => (forall b. Data b => b -> b) -> a -> a
    gmapT ((Type -> Type) -> b -> b
    forall a. Data a => (Type -> Type) -> a -> a
    transformTypes Type -> Type
    f) (a -> a) -> (String -> String) -> a -> a
    forall a b.
    (Typeable a, Typeable b) =>
    (a -> a) -> (b -> b) -> a -> a
    `extT` (String -> String
    forall a. a -> a
    id :: String -> String) (a -> a) -> (Type -> Type) -> a -> a
    forall a b.
    (Typeable a, Typeable b) =>
    (a -> a) -> (b -> b) -> a -> a
    `extT` Type -> Type
    f