Q 型

Language.Haskell.TH.Syntax 中定义的 Q :: * -> *类型构造函数是一种抽象类型,表示可以访问运行计算的模块的编译时环境的计算。Q 类型也处理可变替换,称为 TH 的名称捕获 (在讨论。)所有接头都有一些 Q X 用于某些 X

编译时环境包括:

  • 范围内标识符和有关所述标识符的信息,
    • 功能类型
    • 构造函数的类型和源数据类型
    • 类型声明的完整规范(类,类型系列)
  • 发生拼接的源代码(行,列,模块,包)中的位置
  • 功能的固定性(GHC 7.10)
  • 启用 GHC 扩展(GHC 8.0)

Q 类型还具有生成新名称的功能,功能 newName::String -> Q Name。请注意,该名称不是隐式绑定的,因此用户必须自己绑定它,因此确保使用该名称的结果是用户的责任。

QFunctor,Monad,Applicative 的实例,这是操作 Q 值的主界面,以及 Language.Haskell.TH.Lib 中提供的组合器,它们为形式的 TH ast 的每个构造函数定义一个辅助函数:

LitE::Lit -> Exp
litE::Lit -> ExpQ

AppE::Exp -> Exp -> Exp 
appE::ExpQ -> ExpQ -> ExpQ

注意,ExpQTypeQDecsQPatQ 是 AST 类型的同义词,它们通常存储在 Q 类型中。

TH 库提供了一个函数 runQ::Quasi m => Q a -> m a,并且有一个实例 Quasi IO,所以看起来 Q 类型只是一个花哨的 IO。但是,runQ::Q a -> IO a 的使用产生了一个 IO 动作,它无法访问任何编译时环境 - 这只能在实际的 Q 类型中使用。如果尝试访问所述环境,此类 IO 操作将在运行时失败。