Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I easily see the output from a Template Haskell statement?

I have the following Template Haskell code in my module, which is part of a larger application.

$(derive makeFoldable ''JStatement)

I suspect that the generated instance of Foldable is not exactly what I originally had in mind, but I can't find a way to verify this. So, preferrably using only ghci, is it possible to view the generated instance?

I tried the following and got a syntax error and I'm guessing this is because I'm Doing It Wrong™.

> derive makeFoldable ''JStatement

<interactive>:1:21:
    lexical error in string/character literal at character '\''
like image 712
Deniz Dogan Avatar asked Apr 19 '09 19:04

Deniz Dogan


2 Answers

I figured it out. If you pass -ddump-splices it will print the generated instances to the terminal when compiling the module.

like image 124
Deniz Dogan Avatar answered Nov 06 '22 07:11

Deniz Dogan


GHCi reports "lexical error..." because you don't have Template Haskell activated in your GHCi session. You can activate it either by passing -XTemplateHaskell on the command line or from within GHCi itself:

ghci> :set -XTemplateHaskell

After fixing that, you should get an error in the likes of:

No instance for (Show DecsQ) arising from a use of ‘print’
In a stmt of an interactive GHCi command: print it

Now, you have several options to print things that are inside the Q monad:

  • Use -ddump-splices (as already pointed out in Deniz Dogan's answer)

  • Pretty print the generated Haskell code from GHCi itself:

    > putStrLn $(stringE . pprint =<< derive makeFoldable ''JStatement)
    instance Foldable (JStatement ...)
      where foldr ... = ...
    
  • Show the actual structure based on constructors:

    > putStrLn $(stringE . show =<< derive makeFoldable ''JStatement)
    [InstanceD [] (AppT (ConT Foldable) (... JStatement ...)) [...]]
    

The last two might be simplified using runQ, but this does not work for code generation that uses some Template Haskell functions, such as reify operations. This includes some (or maybe most?) derivations of the derive package.

like image 44
Rudy Matela Avatar answered Nov 06 '22 07:11

Rudy Matela