Joachim Breitner's Homepage
Template Haskell recompilation
I was wondering: What happens if I have a Haskell module with Template Haskell that embeds some information from the environment (time, environment variables). Will such a module be reliable recompiled? And what if it gets recompiled, but the source code produced by Template Haskell is actually unchanged (e.g., because the environment variable has not changed), will all depending modules be recompiled (which would be bad)?
Here is a quick experiment, using GHC-8.8:
/tmp/th-recom-test $ cat Foo.hs
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -fforce-recomp #-}
module Foo where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import System.Process
theMinute :: String
theMinute = $(runIO (readProcess "date" ["+%M"] "") >>= stringE)
[jojo@kirk:2] Mi, der 01.07.2020 um 17:18 Uhr ☺
/tmp/th-recom-test $ cat Main.hs
import Foo
main = putStrLn theMinute
Note that I had to set {-# OPTIONS_GHC -fforce-recomp #-}
– by default, GHC will not recompile a module, even if it uses Template Haskell and runIO
. If you are reading from a file you can use addDependentFile
to tell the compiler about that depenency, but that does not help with reading from the environment.
So here is the test, and we get the desired behaviour: The Foo
module is recompiled every time, but unless the minute has changed (see my prompt), Main
is not recomipled:
/tmp/th-recom-test $ ghc --make -O2 Main.hs -o test
[1 of 2] Compiling Foo ( Foo.hs, Foo.o )
[2 of 2] Compiling Main ( Main.hs, Main.o )
Linking test ...
[jojo@kirk:2] Mi, der 01.07.2020 um 17:20 Uhr ☺
/tmp/th-recom-test $ ghc --make -O2 Main.hs -o test
[1 of 2] Compiling Foo ( Foo.hs, Foo.o )
Linking test ...
[jojo@kirk:2] Mi, der 01.07.2020 um 17:20 Uhr ☺
/tmp/th-recom-test $ ghc --make -O2 Main.hs -o test
[1 of 2] Compiling Foo ( Foo.hs, Foo.o )
[2 of 2] Compiling Main ( Main.hs, Main.o ) [Foo changed]
Linking test ...
So all well!
Update: It seems that while this works with ghc --make
, the -fforce-recomp
does not cause cabal build
to rebuild the module. That’s unfortunate.
Have something to say? You can post a comment by sending an e-Mail to me at <mail@joachim-breitner.de>, and I will include it here.