これに答えるには、準引用符が何であるかを知ることが役に立ちます。 GHC Documentationから、準クォータは、式のテンプレートHaskellの表現である、ExpQ
、PatQ
、TypeQ
、及びDecQ
の1つ以上に任意の文字列からパーサの、ある
data QuasiQuoter = QuasiQuoter { quoteExp :: String -> Q Exp,
quotePat :: String -> Q Pat,
quoteType :: String -> Q Type,
quoteDec :: String -> Q [Dec] }
の値であります、パターン、型、および宣言をそれぞれ示します。
擬似引用符を使用すると、GHCはパーサーを文字列に適用してExpQ
(または他の型)を作成し、結果のテンプレートhaskell式をスプライスして実際の値を生成します。
TH式にアクセスできるように、quasiquoteの解析とスプライシングを分離することをお勧めします。次に、その式を別のモジュールにインポートして、そこにスプライスすることができます。
準引用符のタイプを知っていれば、これが可能であることは容易にわかります。通常は
-- file Expr.hs
eval :: Expr -> Integer
expr = QuasiQuoter { quoteExp = parseExprExp, quotePat = parseExprPat }
-- file Foo.hs
import Expr
myInt = eval [expr|1 + 2|]
としてQQを使用する代わりに、あなたは、パーサを自分で抽出TH表現を取得し、後でそれをスプライスすることができます:もちろん
-- file Foo.hs
import Expr
-- run the QQ parser
myInt_TH :: ExpQ
myInt_TH = quoteExp expr "1 + 2"
-- file Bar.hs
import Foo.hs
-- run the TH splice
myInt = $(myInt_TH)
をあなたはこのすべてを自分で書いている場合は、準引用符をスキップし、パーサとTemplate Haskellを直接使用することができます。それはいずれの方法でもほとんど同じことです。
あなたがこれで達成しようとしていることを言えば助けになると思います。技術的には、THはコンパイルされているモジュールの読み込みや解析を含む任意のIOを実行できるため、異なる場所や異なるモジュールから物を取り込むことができますが、詳細は実行しようとしていることに依存します。 – hammar