ghc-internal-9.1500.0: Basic libraries
Safe HaskellTrustworthy
LanguageHaskell2010

GHC.Internal.TH.Monad

Description

This module is used internally in GHC's integration with Template Haskell and defines the Monads of Template Haskell, and associated definitions.

This is not a part of the public API, and as such, there are no API guarantees for this module from version to version.

Import Language.Haskell.TH or Language.Haskell.TH.Syntax instead!

Synopsis

Documentation

addCorePlugin :: String -> Q () Source #

Adds a core plugin to the compilation pipeline.

addCorePlugin m has almost the same effect as passing -fplugin=m to ghc in the command line. The major difference is that the plugin module m must not belong to the current package. When TH executes, it is too late to tell the compiler that we needed to compile first a plugin module in the current package.

addDependentDirectory :: FilePath -> Q () Source #

Record external directories that runIO is using (dependent upon). The compiler can then recognize that it should re-compile the Haskell file when a directory changes.

Notes:

  • ghc -M does not know about these dependencies - it does not execute TH.
  • The dependency is shallow, based only on the direct content. Basically, it only sees a list of names. It does not look at directory metadata, recurse into subdirectories, or look at file contents. As long as the list of names remains the same, the directory is considered unchanged.
  • The state of the directory is read at the interface generation time, not at the time of the function call.

addDependentFile :: FilePath -> Q () Source #

Record external files that runIO is using (dependent upon). The compiler can then recognize that it should re-compile the Haskell file when an external file changes.

Expects an absolute file path.

Notes:

  • ghc -M does not know about these dependencies - it does not execute TH.
  • The dependency is based on file content, not a modification time

addForeignFilePath :: ForeignSrcLang -> FilePath -> Q () Source #

Same as addForeignSource, but expects to receive a path pointing to the foreign file instead of a String of its contents. Consider using this in conjunction with addTempFile.

This is a good alternative to addForeignSource when you are trying to directly link in an object file.

addForeignSource :: ForeignSrcLang -> String -> Q () Source #

Emit a foreign file which will be compiled and linked to the object for the current module. Currently only languages that can be compiled with the C compiler are supported, and the flags passed as part of -optc will be also applied to the C compiler invocation that will compile them.

Note that for non-C languages (for example C++) extern C directives must be used to get symbols that we can access from Haskell.

To get better errors, it is recommended to use #line pragmas when emitting C files, e.g.

{-# LANGUAGE CPP #-}
...
addForeignSource LangC $ unlines
  [ "#line " ++ show (862 + 1) ++ " " ++ show "libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs"
  , ...
  ]

addModFinalizer :: Q () -> Q () Source #

Add a finalizer that will run in the Q monad after the current module has been type checked. This only makes sense when run within a top-level splice.

The finalizer is given the local type environment at the splice point. Thus reify is able to find the local definitions when executed inside the finalizer.

addTempFile :: String -> Q FilePath Source #

Obtain a temporary file path with the given suffix. The compiler will delete this file after compilation.

addTopDecls :: [Dec] -> Q () Source #

Add additional top-level declarations. The added declarations will be type checked along with the current declaration group.

bindCode :: Monad m => m a -> (a -> Code m b) -> Code m b Source #

Variant of (>>=) which allows effectful computations to be injected into code generation.

bindCode_ :: Monad m => m a -> Code m b -> Code m b Source #

Variant of (>>) which allows effectful computations to be injected into code generation.

extsEnabled :: Q [Extension] Source #

List all enabled language extensions.

getDoc :: DocLoc -> Q (Maybe String) Source #

Retrieves the Haddock documentation at the specified location, if one exists. It can be used to read documentation on things defined outside of the current module, provided that those modules were compiled with the -haddock flag.

getPackageRoot :: Q FilePath Source #

Get the package root for the current package which is being compiled. This can be set explicitly with the -package-root flag but is normally just the current working directory.

The motivation for this flag is to provide a principled means to remove the assumption from splices that they will be executed in the directory where the cabal file resides. Projects such as haskell-language-server can't and don't change directory when compiling files but instead set the -package-root flag appropriately.

getQ :: Typeable a => Q (Maybe a) Source #

Get state from the Q monad. Note that the state is local to the Haskell module in which the Template Haskell expression is executed.

hoistCode :: Monad m => (forall x. m x -> n x) -> Code m a -> Code n a Source #

Modify the ambient monad used during code generation. For example, you can use hoistCode to handle a state effect: handleState :: Code (StateT Int Q) a -> Code Q a handleState = hoistCode (flip runState 0)

isExtEnabled :: Extension -> Q Bool Source #

Determine whether the given language extension is enabled in the Q monad.

isInstance :: Name -> [Type] -> Q Bool Source #

Is the list of instances returned by reifyInstances nonempty?

If you're confused by an instance not being visible despite being defined in the same module and above the splice in question, see the docs for newDeclarationGroup for a possible explanation.

joinCode :: Monad m => m (Code m a) -> Code m a Source #

A useful combinator for embedding monadic actions into Code myCode :: ... => Code m a myCode = joinCode $ do x <- someSideEffect return (makeCodeWith x)

liftCode :: forall a m. m (TExp a) -> Code m a Source #

Lift a monadic action producing code into the typed Code representation

location :: Q Loc Source #

The location at which this computation is spliced.

lookupTypeName :: String -> Q (Maybe Name) Source #

Look up the given name in the (type namespace of the) current splice's scope. See Language.Haskell.TH.Syntax for more details.

lookupValueName :: String -> Q (Maybe Name) Source #

Look up the given name in the (value namespace of the) current splice's scope. See Language.Haskell.TH.Syntax for more details.

newDeclarationGroup :: Q [Dec] Source #

Template Haskell is capable of reifying information about types and terms defined in previous declaration groups. Top-level declaration splices break up declaration groups.

For an example, consider this code block. We define a datatype X and then try to call reify on the datatype.

module Check where

data X = X
    deriving Eq

$(do
    info <- reify ''X
    runIO $ print info
 )

This code fails to compile, noting that X is not available for reification at the site of reify. We can fix this by creating a new declaration group using an empty top-level splice:

data X = X
    deriving Eq

$(pure [])

$(do
    info <- reify ''X
    runIO $ print info
 )

We provide newDeclarationGroup as a means of documenting this behavior and providing a name for the pattern.

Since top level splices infer the presence of the $( ... ) brackets, we can also write:

data X = X
    deriving Eq

newDeclarationGroup

$(do
    info <- reify ''X
    runIO $ print info
 )

putDoc :: DocLoc -> String -> Q () Source #

Add Haddock documentation to the specified location. This will overwrite any documentation at the location if it already exists. This will reify the specified name, so it must be in scope when you call it. If you want to add documentation to something that you are currently splicing, you can use addModFinalizer e.g.

do
  let nm = mkName "x"
  addModFinalizer $ putDoc (DeclDoc nm) "Hello"
  [d| $(varP nm) = 42 |]

The helper functions withDecDoc and withDecsDoc will do this for you, as will the funD_doc and other _doc combinators. You most likely want to have the -haddock flag turned on when using this. Adding documentation to anything outside of the current module will cause an error.

putQ :: Typeable a => a -> Q () Source #

Replace the state in the Q monad. Note that the state is local to the Haskell module in which the Template Haskell expression is executed.

recover Source #

Arguments

:: Q a

handler to invoke on failure

-> Q a

computation to run

-> Q a 

Recover from errors raised by reportError or fail.

reify :: Name -> Q Info Source #

reify looks up information about the Name. It will fail with a compile error if the Name is not visible. A Name is visible if it is imported or defined in a prior top-level declaration group. See the documentation for newDeclarationGroup for more details.

It is sometimes useful to construct the argument name using lookupTypeName or lookupValueName to ensure that we are reifying from the right namespace. For instance, in this context:

data D = D

which D does reify (mkName "D") return information about? (Answer: D-the-type, but don't rely on it.) To ensure we get information about D-the-value, use lookupValueName:

do
  Just nm <- lookupValueName "D"
  reify nm

and to get information about D-the-type, use lookupTypeName.

reifyAnnotations :: Data a => AnnLookup -> Q [a] Source #

reifyAnnotations target returns the list of annotations associated with target. Only the annotations that are appropriately typed is returned. So if you have Int and String annotations for the same target, you have to call this function twice.

reifyConStrictness :: Name -> Q [DecidedStrictness] Source #

reifyConStrictness nm looks up the strictness information for the fields of the constructor with the name nm. Note that the strictness information that reifyConStrictness returns may not correspond to what is written in the source code. For example, in the following data declaration:

data Pair a = Pair a a

reifyConStrictness would return [DecidedLazy, DecidedLazy] under most circumstances, but it would return [DecidedStrict, DecidedStrict] if the -XStrictData language extension was enabled.

reifyFixity :: Name -> Q (Maybe Fixity) Source #

reifyFixity nm attempts to find a fixity declaration for nm. For example, if the function foo has the fixity declaration infixr 7 foo, then reifyFixity 'foo would return Just (Fixity 7 InfixR). If the function bar does not have a fixity declaration, then reifyFixity 'bar returns Nothing, so you may assume bar has defaultFixity.

reifyInstances :: Name -> [Type] -> Q [InstanceDec] Source #

reifyInstances nm tys returns a list of all visible instances (see below for "visible") of nm tys. That is, if nm is the name of a type class, then all instances of this class at the types tys are returned. Alternatively, if nm is the name of a data family or type family, all instances of this family at the types tys are returned.

Note that this is a "shallow" test; the declarations returned merely have instance heads which unify with nm tys, they need not actually be satisfiable.

  • reifyInstances ''Eq [ TupleT 2 `AppT` ConT ''A `AppT` ConT ''B ] contains the instance (Eq a, Eq b) => Eq (a, b) regardless of whether A and B themselves implement Eq
  • reifyInstances ''Show [ VarT (mkName "a") ] produces every available instance of Show

There is one edge case: reifyInstances ''Typeable tys currently always produces an empty list (no matter what tys are given).

In principle, the *visible* instances are * all instances defined in a prior top-level declaration group (see docs on newDeclarationGroup), or * all instances defined in any module transitively imported by the module being compiled

However, actually searching all modules transitively below the one being compiled is unreasonably expensive, so reifyInstances will report only the instance for modules that GHC has had some cause to visit during this compilation. This is a shortcoming: reifyInstances might fail to report instances for a type that is otherwise unusued, or instances defined in a different component. You can work around this shortcoming by explicitly importing the modules whose instances you want to be visible. GHC issue #20529 has some discussion around this.

reifyModule :: Module -> Q ModuleInfo Source #

reifyModule mod looks up information about module mod. To look up the current module, call this function with the return value of thisModule.

reifyRoles :: Name -> Q [Role] Source #

reifyRoles nm returns the list of roles associated with the parameters (both visible and invisible) of the tycon nm. Fails if nm cannot be found or is not a tycon. The returned list should never contain InferR.

An invisible parameter to a tycon is often a kind parameter. For example, if we have

type Proxy :: forall k. k -> Type
data Proxy a = MkProxy

and reifyRoles Proxy, we will get [NominalR, PhantomR]. The NominalR is the role of the invisible k parameter. Kind parameters are always nominal.

reifyType :: Name -> Q Type Source #

reifyType nm attempts to find the type or kind of nm. For example, reifyType 'not returns Bool -> Bool, and reifyType ''Bool returns Type. This works even if there's no explicit signature and the type or kind is inferred.

report :: Bool -> String -> Q () Source #

Deprecated: Use reportError or reportWarning instead

Report an error (True) or warning (False), but carry on; use fail to stop.

reportError :: String -> Q () Source #

Report an error to the user, but allow the current splice's computation to carry on. To abort the computation, use fail.

reportWarning :: String -> Q () Source #

Report a warning to the user, and carry on.

runIO :: IO a -> Q a Source #

The runIO function lets you run an I/O computation in the Q monad. Take care: you are guaranteed the ordering of calls to runIO within a single Q computation, but not about the order in which splices are run.

Note: for various murky reasons, stdout and stderr handles are not necessarily flushed when the compiler finishes running, so you should flush them yourself.

runQ :: Quasi m => Q a -> m a Source #

"Runs" the Q monad. Normal users of Template Haskell should not need this function, as the splice brackets $( ... ) are the usual way of running a Q computation.

This function is primarily used in GHC internals, and for debugging splices by running them in IO.

Note that many functions in Q, such as reify and other compiler queries, are not supported when running Q in IO; these operations simply fail at runtime. Indeed, the only operations guaranteed to succeed are newName, runIO, reportError and reportWarning.

sequenceQ :: Monad m => forall a. [m a] -> m [a] Source #

This function is only used in Quote when desugaring brackets. This is not necessary for the user, who can use the ordinary return and (>>=) operations.

unTypeCode :: forall a m. Quote m => Code m a -> m Exp Source #

Extract the untyped representation from the typed representation

unTypeQ :: forall a m. Quote m => m (TExp a) -> m Exp Source #

Discard the type annotation and produce a plain Template Haskell expression

Representation-polymorphic since template-haskell-2.16.0.0.

unsafeCodeCoerce :: forall a m. Quote m => m Exp -> Code m a Source #

Unsafely convert an untyped code representation into a typed code representation.

unsafeTExpCoerce :: forall a m. Quote m => m Exp -> m (TExp a) Source #

Annotate the Template Haskell expression with a type

This is unsafe because GHC cannot check for you that the expression really does have the type you claim it has.

Representation-polymorphic since template-haskell-2.16.0.0.

newtype Code (m :: Type -> Type) (a :: TYPE r) Source #

Represents an expression which has type a, built in monadic context m. Built on top of TExp, typed expressions allow for type-safe splicing via:

  • typed quotes, written as [|| ... ||] where ... is an expression; if that expression has type a, then the quotation has type Quote m => Code m a
  • typed splices inside of typed quotes, written as $$(...) where ... is an arbitrary expression of type Quote m => Code m a

Traditional expression quotes and splices let us construct ill-typed expressions:

>>> fmap ppr $ runQ (unTypeCode [| True == $( [| "foo" |] ) |])
GHC.Internal.Types.True GHC.Internal.Classes.== "foo"
>>> GHC.Internal.Types.True GHC.Internal.Classes.== "foo"
<interactive> error:
    • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
    • In the second argument of ‘(==)’, namely ‘"foo"’
      In the expression: True == "foo"
      In an equation for ‘it’: it = True == "foo"

With typed expressions, the type error occurs when constructing the Template Haskell expression:

>>> fmap ppr $ runQ (unTypeCode [|| True == $$( [|| "foo" ||] ) ||])
<interactive> error:
    • Couldn't match type ‘[Char]’ with ‘Bool’
      Expected type: Code Q Bool
        Actual type: Code Q [Char]
    • In the Template Haskell quotation [|| "foo" ||]
      In the expression: [|| "foo" ||]
      In the Template Haskell splice $$([|| "foo" ||])

Constructors

Code 

Fields

newtype Q a Source #

In short, Q provides the Quasi operations in one neat monad for the user.

The longer story, is that Q wraps an arbitrary Quasi-able monad. The perceptive reader notices that Quasi has only two instances, Q itself and IO, neither of which have concrete implementations.Q plays the trick of dependency inversion, providing an abstract interface for the user which is later concretely fufilled by an concrete Quasi instance, internal to GHC.

Constructors

Q 

Fields

Instances

Instances details
Applicative Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Methods

pure :: a -> Q a Source #

(<*>) :: Q (a -> b) -> Q a -> Q b Source #

liftA2 :: (a -> b -> c) -> Q a -> Q b -> Q c Source #

(*>) :: Q a -> Q b -> Q b Source #

(<*) :: Q a -> Q b -> Q a Source #

Functor Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Methods

fmap :: (a -> b) -> Q a -> Q b Source #

(<$) :: a -> Q b -> Q a Source #

Monad Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Methods

(>>=) :: Q a -> (a -> Q b) -> Q b Source #

(>>) :: Q a -> Q b -> Q b Source #

return :: a -> Q a Source #

MonadFail Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Methods

fail :: HasCallStack => String -> Q a Source #

MonadFix Q Source #

If the function passed to mfix inspects its argument, the resulting action will throw a FixIOException.

Since: ghc-internal-2.17.0.0

Instance details

Defined in GHC.Internal.TH.Monad

Methods

mfix :: (a -> Q a) -> Q a Source #

MonadIO Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Methods

liftIO :: IO a -> Q a Source #

Quasi Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Quote Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Methods

newName :: String -> Q Name Source #

Monoid a => Monoid (Q a) Source #

Since: ghc-internal-2.17.0.0

Instance details

Defined in GHC.Internal.TH.Monad

Methods

mempty :: Q a Source #

mappend :: Q a -> Q a -> Q a Source #

mconcat :: [Q a] -> Q a Source #

Semigroup a => Semigroup (Q a) Source #

Since: ghc-internal-2.17.0.0

Instance details

Defined in GHC.Internal.TH.Monad

Methods

(<>) :: Q a -> Q a -> Q a Source #

sconcat :: NonEmpty (Q a) -> Q a Source #

stimes :: Integral b => b -> Q a -> Q a Source #

class (MonadIO m, MonadFail m) => Quasi (m :: Type -> Type) where Source #

Methods

qNewName :: String -> m Name Source #

Fresh names. See newName.

qReport :: Bool -> String -> m () Source #

Report an error (True) or warning (False) ...but carry on; use fail to stop. See report.

qRecover Source #

Arguments

:: m a

the error handler

-> m a

action which may fail

-> m a

Recover from the monadic fail

See recover.

qLookupName :: Bool -> String -> m (Maybe Name) Source #

True = type namespace, False = value namespace. See lookupName.

qReify :: Name -> m Info Source #

See reify.

qReifyFixity :: Name -> m (Maybe Fixity) Source #

qReifyType :: Name -> m Type Source #

qReifyInstances :: Name -> [Type] -> m [Dec] Source #

Is (n tys) an instance? Returns list of matching instance Decs (with empty sub-Decs) Works for classes and type functions. See reifyInstances.

qReifyRoles :: Name -> m [Role] Source #

qReifyAnnotations :: Data a => AnnLookup -> m [a] Source #

qReifyModule :: Module -> m ModuleInfo Source #

qReifyConStrictness :: Name -> m [DecidedStrictness] Source #

qLocation :: m Loc Source #

qRunIO :: IO a -> m a Source #

Input/output (dangerous). See runIO.

qGetPackageRoot :: m FilePath Source #

qAddDependentFile :: FilePath -> m () Source #

qAddDependentDirectory :: FilePath -> m () Source #

qAddTempFile :: String -> m FilePath Source #

qAddTopDecls :: [Dec] -> m () Source #

qAddForeignFilePath :: ForeignSrcLang -> String -> m () Source #

qAddModFinalizer :: Q () -> m () Source #

qAddCorePlugin :: String -> m () Source #

qGetQ :: Typeable a => m (Maybe a) Source #

See getQ.

qPutQ :: Typeable a => a -> m () Source #

See putQ.

qIsExtEnabled :: Extension -> m Bool Source #

qExtsEnabled :: m [Extension] Source #

qPutDoc :: DocLoc -> String -> m () Source #

See putDoc.

qGetDoc :: DocLoc -> m (Maybe String) Source #

See getDoc.

Instances

Instances details
Quasi Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Quasi IO Source # 
Instance details

Defined in GHC.Internal.TH.Monad

class Monad m => Quote (m :: Type -> Type) where Source #

The Quote class implements the minimal interface which is necessary for desugaring quotations.

  • The Monad m superclass is needed to stitch together the different AST fragments.
  • newName is used when desugaring binding structures such as lambdas to generate fresh names.

Therefore the type of an untyped quotation in GHC is `Quote m => m Exp`

For many years the type of a quotation was fixed to be `Q Exp` but by more precisely specifying the minimal interface it enables the Exp to be extracted purely from the quotation without interacting with Q.

Methods

newName :: String -> m Name Source #

Generate a fresh name, which cannot be captured.

For example, this:

f = $(do
    nm1 <- newName "x"
    let nm2 = mkName "x"
    return (LamE [VarP nm1] (LamE [VarP nm2] (VarE nm1)))
   )

will produce the splice

f = \x0 -> \x -> x0

In particular, the occurrence VarE nm1 refers to the binding VarP nm1, and is not captured by the binding VarP nm2.

Although names generated by newName cannot be captured, they can capture other names. For example, this:

g = $(do
  nm1 <- newName "x"
  let nm2 = mkName "x"
  return (LamE [VarP nm2] (LamE [VarP nm1] (VarE nm2)))
 )

will produce the splice

g = \x -> \x0 -> x0

since the occurrence VarE nm2 is captured by the innermost binding of x, namely VarP nm1.

Instances

Instances details
Quote Q Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Methods

newName :: String -> Q Name Source #

Quote IO Source # 
Instance details

Defined in GHC.Internal.TH.Monad

Methods

newName :: String -> IO Name Source #

newtype TExp (a :: TYPE r) Source #

Typed wrapper around an Exp.

This is the typed representation of terms produced by typed quotes.

Representation-polymorphic since template-haskell-2.16.0.0.

Constructors

TExp 

Fields

  • unType :: Exp

    Underlying untyped Template Haskell expression

Instances

Instances details
Lift (TExp a :: Type) Source #

Since: template-haskell-2.22.1.0

Instance details

Defined in GHC.Internal.TH.Lift

Methods

lift :: Quote m => TExp a -> m Exp Source #

liftTyped :: forall (m :: Type -> Type). Quote m => TExp a -> Code m (TExp a) Source #