Quote module contents into a string with Template Haskell
I have a program with static configuration in module named Config. There is a bunch of constants like this:
extractCtxs'ctxSize :: Int extractCtxs'ctxSize = 300 extractCtxs'sparse :: Bool extractCtxs'sparse = True selectWords'dropBorder :: Int selectWords'dropBorder = 20000 selectWords'takeCount :: Int selectWords'takeCount = 100
Now suppose I want to quote this module elsewhere and include it’s contents into an output file for record: “This file was produced with the following settings: <Config module contents goes here>”. There are many ways to do that the simplest being copying the whole module into a string and updating it everytime a change is made.
My solution involves Template Haskell. Turns out you can execute any IO action during compilation. All you really need to do is read a file and produce a literal string containing it. Here is the whole module:
{-# LANGUAGE TemplateHaskell #-}
module Config where
import Language.Haskell.TH
import Data.List.Split (splitOn)
-- START
-- extractCtxs'dumpSize :: Int
-- extractCtxs'dumpSize = 100000
extractCtxs'ctxSize :: Int
extractCtxs'ctxSize = 300
extractCtxs'sparse :: Bool
extractCtxs'sparse = True
selectWords'dropBorder :: Int
selectWords'dropBorder = 20000
selectWords'takeCount :: Int
selectWords'takeCount = 100
-- STOP
config' = $(do
s <- runIO $ readFile "lib/Config.hs"
return $ LitE $ stringL s)
config = head . splitOn "-- STOP" . head . tail . splitOn "-- START" $ config'
This gist contains the above module with syntax highlighting. Config.config contains the configuration part. Config.config’ contains the whole module code. Pretty simple, really.
