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 操作將在執行時失敗。