Когда Cabal перекомпилирует модуль, содержащий Template Haskell? - PullRequest
0 голосов
/ 04 ноября 2018

Я понимаю, что 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 закомментирована.

В чем причина этого, и есть ли способ избежать этой ненужной перекомпиляции?

1 Ответ

0 голосов
/ 04 ноября 2018

В Template Haskell есть функция под названием addDependentFile, которая добавляет метаданные в файл .hi, указывая, что рассматриваемый исходный файл зависит также и от другого файла. Насколько мне известно, Кабал будет всегда просить GHC попытаться построить, хотя он может иметь более разумную логику. Стек пытается обойти этот процесс и имеет логику для анализа информации addDependentFile.

...