I find myself writing a lot of code like
putStr "foo (bar 1) (bar 2) =" print $ foo (bar 1) (bar 2)
The trouble is, the printed message can get out of sync with the actual executed code. The obvious solution is to auto-generate this code.
One way to do that would be to put all the text in a file, and write a small program that reads the file and generates Haskell source code from it. But another alternative is to use Template Haskell.
Does anybody know how I would go about writing a function that takes a String
and generates the above code from it? I'm guessing it should be pretty easy, but TH is not well documented.
You can parse Haskell code using the haskell-src-meta
package. Here's a quick example how you could combine this with Template Haskell.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Language.Haskell.Meta
runShow = QuasiQuoter
{ quoteExp = runShowQQ
, quotePat = undefined
, quoteType = undefined
, quoteDec = undefined
}
runShowQQ :: String -> Q Exp
runShowQQ s = do
let s' = s ++ " = "
Right exp = parseExp s
printExp = appE [|print|] (return exp)
infixApp [|putStr s'|] [|(>>)|] printExp
And you would use it like this
{-# LANGUAGE QuasiQuotes #-}
[runShow|foo (bar 1) (bar 2)|]