I understand that cabal will recompile a module if the interface of any of its dependencies has changed. It seems that this simple rule does not hold if the module contains Template Haskell. In that case, even just adding a trailing newline character to a file in the module's (transitive) dependencies will cause the cabal to recompile the file.
Minimal example:
file: Foo.hs
module Foo where
foo = "foo"
file: FooTH.hs
{-# LANGUAGE TemplateHaskell #-}
module FooTH where
import Data.Bifunctor.TH
import Foo
data FooPair a b = FooPair a b
$(deriveBifunctor ''FooPair)
file: MCVE.cabal
name: MCVE
version: 0.1.0.0
synopsis: MCVE
license: MIT
license-file: LICENSE
author: tarleb
maintainer: tarleb@example.com
build-type: Simple
extra-source-files: CHANGELOG.md
cabal-version: >=1.10
library
exposed-modules: Foo
, FooTH
build-depends: base >=4.8 && <4.13
, bifunctors
default-language: Haskell2010
Adding a newline to Foo.hs, e.g. by running echo "\n" >> Foo.hs
, will cause recompilation of module FooTH. This ceases to happen if the TH line in FooTH is commented out.
What is the reason for this, and is there a way to avoid this unnecessary recompilation?