45

ご存知のように、Template Haskell は、コンパイル時にさまざまな種類の AST スプライスをプログラムで生成するために使用されます。

ただし、スプライスは非常に不透明な場合が多く、スプライスが実際に生成するものを識別するのが難しい場合がよくあります。スプライスのモナドを実行しQ、スプライスが適切に型付けされている場合show、生成された AST の部分を適切に表現できますが、構造化されていないレイアウトのため、この表現は非常に理解しにくい場合があります。

TH で生成された AST の一部を通常の Haskell コードに似たものに変換して、コードを簡単に読み取って理解できるようにするための推奨される方法は何ですか? たとえば、与えられた値からソースコードを再構築できDecますか? GHC Core コードを読む必要はありますか? 少なくとも AST を構造化して読みやすくする方法はありますか (たとえば、pretty-showパッケージが行うことを超えて)。

4

3 に答える 3

56

-ddump-splicesコンパイラへのフラグを探していますか?

于 2011-12-15T14:11:05.267 に答える
25

あなたはLanguage.Haskell.TH.Ppr ( Language.Haskell.THで自動的にインポートされる)を使用pprintすることができるかもしれません:ppr

GHCi> expr <- runQ [| \f g x -> f (x*2 + 3) . g |]
GHCi> putStrLn $ pprint expr
\f_0 g_1 x_2 -> f_0 ((x_2 GHC.Num.* 2) GHC.Num.+ 3) GHC.Base.. g_1

きれいではありませんが、Haskellは有効です。プレリュード名からモジュールプレフィックスを取り除くことで、出力をより良くすることができるはずです(ただし、予想されるプレフィックスのみを取り除くように注意する必要があるかもしれませんFoo.*。結局のところ、完全に有効な中置演算子です)。

于 2011-12-15T14:44:26.637 に答える
1

ehird answerの補足として:

runQ一般に、GHCi から直接使用するとうまくいかない可能性があることに注意してください(例:reify演算を使用する TH ジェネレータ。 runQ 宣言の上のコメントを参照)。

それが失敗した場合は、pprint(またはshow)文字列式に変換stringEしてから、引数としてスプライスすることができますputStrLn

> putStrLn $(stringE . pprint =<< [| \f g x -> f (x*2 + 3) . g |])
\f_0 g_1 x_2 -> f_0 ((x_2 GHC.Num.* 2) GHC.Num.+ 3) GHC.Base.. g_1
于 2015-12-14T22:01:50.400 に答える