Take the 2-minute tour ×

As you know, Template Haskell is used to generate various kinds of AST splices programmatically at compile-time.

However, a splice can often be very opaque, and it is often difficult to discern what a splice actually generates. If you run the Q monad for a splice, and the splice is well-typed, you get a showable representation of the generated piece of AST, but this representation can be very difficult to understand, because of its unstructured layout.

What is the preferred method for converting a piece of TH-generated AST into something akin to normal Haskell code, so that the code can be easily read and understood? Can one reconstruct source code from e.g. a given Dec value? Does one have to read the GHC Core code? Is there a way to at least structure the AST so that it becomes more readable (Beyond what e.g. the pretty-show package does)?

share|improve this question

2 Answers 2

up vote 15 down vote accepted

You may be able to use pprint or ppr from Language.Haskell.TH.Ppr (imported automatically with Language.Haskell.TH):

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

It's not pretty, but it is valid Haskell. You should be able to make the output nicer by stripping off module prefixes from Prelude names (although you might need to be careful to only strip the expected prefix; Foo.* is a perfectly valid infix operator, after all).

share|improve this answer
This solves the part of the question that @augustss didn't answer. –  dflemstr Dec 15 '11 at 14:49

Are you looking for the -ddump-splices flag to the compiler?

share|improve this answer
Yes, this kind of output is precisely what I'm looking for! But can this be done in a program too given only a syntax tree, or does it require the invocation of the compiler? –  dflemstr Dec 15 '11 at 14:25
note: make sure you remove .hi and .o files to get a clean build before you run this, or you won't get any stderr output. –  singular Sep 18 at 23:27

Your Answer


