    -- | Metaprogramming types
    module GHC.Types.Meta
       ( MetaRequest(..)
       , MetaHook
       , MetaResult -- data constructors not exported to ensure correct response type
       , metaRequestE
       , metaRequestP
       , metaRequestT
       , metaRequestD
       , metaRequestAW
       )
    where

    import GHC.Prelude

    import GHC.Serialized   ( Serialized )

    import GHC.Hs

    -- | The supported metaprogramming result types
    data MetaRequest
      = MetaE  (LHsExpr GhcPs   -> MetaResult)
      | MetaP  (LPat GhcPs      -> MetaResult)
      | MetaT  (LHsType GhcPs   -> MetaResult)
      | MetaD  ([LHsDecl GhcPs] -> MetaResult)
      | MetaAW (Serialized     -> MetaResult)

    -- | data constructors not exported to ensure correct result type
    data MetaResult
      = MetaResE  { MetaResult -> LHsExpr GhcPs
    unMetaResE  :: LHsExpr GhcPs   }
      | MetaResP  { MetaResult -> LPat GhcPs
    unMetaResP  :: LPat GhcPs      }
      | MetaResT  { MetaResult -> LHsType GhcPs
    unMetaResT  :: LHsType GhcPs   }
      | MetaResD  { MetaResult -> [LHsDecl GhcPs]
    unMetaResD  :: [LHsDecl GhcPs] }
      | MetaResAW { MetaResult -> Serialized
    unMetaResAW :: Serialized      }

    type MetaHook f = MetaRequest -> LHsExpr GhcTc -> f MetaResult

    metaRequestE :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LHsExpr GhcPs)
    metaRequestE :: forall (f :: * -> *).
    Functor f =>
    MetaHook f -> LHsExpr GhcTc -> f (LHsExpr GhcPs)
    metaRequestE MetaHook f
    h = (MetaResult -> GenLocated SrcSpanAnnA (HsExpr GhcPs))
    -> f MetaResult -> f (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap MetaResult -> LHsExpr GhcPs
    MetaResult -> GenLocated SrcSpanAnnA (HsExpr GhcPs)
    unMetaResE (f MetaResult -> f (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
    -> GenLocated SrcSpanAnnA (HsExpr GhcTc)
    -> f (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MetaHook f
    h ((LHsExpr GhcPs -> MetaResult) -> MetaRequest
    MetaE LHsExpr GhcPs -> MetaResult
    MetaResE)

    metaRequestP :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LPat GhcPs)
    metaRequestP :: forall (f :: * -> *).
    Functor f =>
    MetaHook f -> LHsExpr GhcTc -> f (LPat GhcPs)
    metaRequestP MetaHook f
    h = (MetaResult -> GenLocated SrcSpanAnnA (Pat GhcPs))
    -> f MetaResult -> f (GenLocated SrcSpanAnnA (Pat GhcPs))
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap MetaResult -> LPat GhcPs
    MetaResult -> GenLocated SrcSpanAnnA (Pat GhcPs)
    unMetaResP (f MetaResult -> f (GenLocated SrcSpanAnnA (Pat GhcPs)))
    -> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
    -> GenLocated SrcSpanAnnA (HsExpr GhcTc)
    -> f (GenLocated SrcSpanAnnA (Pat GhcPs))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MetaHook f
    h ((LPat GhcPs -> MetaResult) -> MetaRequest
    MetaP LPat GhcPs -> MetaResult
    MetaResP)

    metaRequestT :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LHsType GhcPs)
    metaRequestT :: forall (f :: * -> *).
    Functor f =>
    MetaHook f -> LHsExpr GhcTc -> f (LHsType GhcPs)
    metaRequestT MetaHook f
    h = (MetaResult -> GenLocated SrcSpanAnnA (HsType GhcPs))
    -> f MetaResult -> f (GenLocated SrcSpanAnnA (HsType GhcPs))
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap MetaResult -> LHsType GhcPs
    MetaResult -> GenLocated SrcSpanAnnA (HsType GhcPs)
    unMetaResT (f MetaResult -> f (GenLocated SrcSpanAnnA (HsType GhcPs)))
    -> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
    -> GenLocated SrcSpanAnnA (HsExpr GhcTc)
    -> f (GenLocated SrcSpanAnnA (HsType GhcPs))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MetaHook f
    h ((LHsType GhcPs -> MetaResult) -> MetaRequest
    MetaT LHsType GhcPs -> MetaResult
    MetaResT)

    metaRequestD :: Functor f => MetaHook f -> LHsExpr GhcTc -> f [LHsDecl GhcPs]
    metaRequestD :: forall (f :: * -> *).
    Functor f =>
    MetaHook f -> LHsExpr GhcTc -> f [LHsDecl GhcPs]
    metaRequestD MetaHook f
    h = (MetaResult -> [GenLocated SrcSpanAnnA (HsDecl GhcPs)])
    -> f MetaResult -> f [GenLocated SrcSpanAnnA (HsDecl GhcPs)]
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap MetaResult -> [LHsDecl GhcPs]
    MetaResult -> [GenLocated SrcSpanAnnA (HsDecl GhcPs)]
    unMetaResD (f MetaResult -> f [GenLocated SrcSpanAnnA (HsDecl GhcPs)])
    -> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
    -> GenLocated SrcSpanAnnA (HsExpr GhcTc)
    -> f [GenLocated SrcSpanAnnA (HsDecl GhcPs)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MetaHook f
    h (([LHsDecl GhcPs] -> MetaResult) -> MetaRequest
    MetaD [LHsDecl GhcPs] -> MetaResult
    MetaResD)

    metaRequestAW :: Functor f => MetaHook f -> LHsExpr GhcTc -> f Serialized
    metaRequestAW :: forall (f :: * -> *).
    Functor f =>
    MetaHook f -> LHsExpr GhcTc -> f Serialized
    metaRequestAW MetaHook f
    h = (MetaResult -> Serialized) -> f MetaResult -> f Serialized
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap MetaResult -> Serialized
    unMetaResAW (f MetaResult -> f Serialized)
    -> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
    -> GenLocated SrcSpanAnnA (HsExpr GhcTc)
    -> f Serialized
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MetaHook f
    h ((Serialized -> MetaResult) -> MetaRequest
    MetaAW Serialized -> MetaResult
    MetaResAW)