Q 型
Language.Haskell.TH.Syntax
中定義的 Q :: * -> *
型別建構函式是一種抽象型別,表示可以訪問執行計算的模組的編譯時環境的計算。Q
型別也處理可變替換,稱為 TH 的名稱捕獲 (在此討論。)所有接頭都有一些 Q X
用於某些 X
。
編譯時環境包括:
- 範圍內識別符號和有關所述識別符號的資訊,
- 功能型別
- 建構函式的型別和源資料型別
- 型別宣告的完整規範(類,型別系列)
- 發生拼接的原始碼(行,列,模組,包)中的位置
- 功能的固定性(GHC 7.10)
- 啟用 GHC 擴充套件(GHC 8.0)
Q
型別還具有生成新名稱的功能,功能 newName::String -> Q Name
。請注意,該名稱不是隱式繫結的,因此使用者必須自己繫結它,因此確保使用該名稱的結果是使用者的責任。
Q
有 Functor,Monad,Applicative
的例項,這是操作 Q
值的主介面,以及 Language.Haskell.TH.Lib
中提供的組合器,它們為形式的 TH ast 的每個建構函式定義一個輔助函式:
LitE::Lit -> Exp
litE::Lit -> ExpQ
AppE::Exp -> Exp -> Exp
appE::ExpQ -> ExpQ -> ExpQ
注意,ExpQ
,TypeQ
,DecsQ
和 PatQ
是 AST 型別的同義詞,它們通常儲存在 Q
型別中。
TH 庫提供了一個函式 runQ::Quasi m => Q a -> m a
,並且有一個例項 Quasi IO
,所以看起來 Q
型別只是一個花哨的 IO
。但是,runQ::Q a -> IO a
的使用產生了一個 IO
動作,它無法訪問任何編譯時環境 - 這只能在實際的 Q
型別中使用。如果嘗試訪問所述環境,此類 IO
操作將在執行時失敗。