Я понимаю, что cabal перекомпилирует модуль, если интерфейс какой-либо из его зависимостей изменился. Кажется, что это простое правило не выполняется, если модуль содержит Template Haskell. В этом случае даже простое добавление завершающего символа новой строки в файл в зависимостях модуля (транзитивных) приведет к перекомпиляции файла кабалой.
Минимальный пример:
файл: Foo.hs
module Foo where
foo = "foo"
файл: FooTH.hs
{-# LANGUAGE TemplateHaskell #-}
module FooTH where
import Data.Bifunctor.TH
import Foo
data FooPair a b = FooPair a b
$(deriveBifunctor ''FooPair)
файл: 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
Добавление новой строки в Foo.hs, например выполнение echo "\n" >> Foo.hs
приведет к перекомпиляции модуля FooTH. Это прекращается, если строка TH в FooTH закомментирована.
В чем причина этого, и есть ли способ избежать этой ненужной перекомпиляции?