如何在没有CPP的情况下最好地适应Cabal库中的类型更改?

时间:2015-04-19 11:44:11

标签: haskell emacs cabal flycheck

我想从.cabal文件中增强flycheck-haskell对自动配置flycheck的支持。

要执行此自动配置,flycheck使用a helper file,其原始策略是读取.cabal文件并使用flattenPackageDescription。这很简单,但不尊重可能导致问题的条件表达式,例如:使用较新版本的bytestring-builder软件包时不需要bytestring

使用的适当界面似乎是finalizePackageDescription。这确实有效...但它的类型签名在1.20和1.22之间变化---现在,它不需要CompilerId,而是现在需要CompilerInfo。但我希望在此API更改中提供一致的支持。

虽然解决方案通常是使用CPP宏,但这些宏由Cabal本身提供,而flycheck只是使用runhaskell调用帮助文件,所以我们无法访问它们。

我能想到的唯一选择是创建另一个帮助器以首先获取Cabal版本信息,然后为我们的{{1}构建适当的CPP设置调用所以我们可以这样做。这应该有效,但看起来像是一个黑客。

所以我在这里寻找其他选项,这些选项可以让我支持这两个版本的界面,而不必诉诸runhaskell

有问题的代码是对CPP的调用,如下所示:

Distribution.PackageDescription.Configuration.finalizePackageDescription

问题是第四个参数case finalizePackageDescription [] (const True) buildPlatform buildCompilerId [] genericDesc' of Left e -> putStrLn $ "Issue with package configuration\n" ++ show e Right (pkgDesc, _) -> print (dumpPackageDescription pkgDesc cabalFile) 将类型从buildCompilerId更改为CompilerId

我已经实现了 - 虽然我很乐意考虑一个更独立的选项---是一个帮助者吐出CompilerInfo(作为一个s-expr,因为我们正在处理Emacs)如果它是Cabal的最新版本:

-DuseCompilerInfo

然后使用该标志运行原始助手,并有条件地导入新结构,并在上述case语句之前具有以下条件代码:

import Data.Version (Version (Version))
import Distribution.Simple.Utils (cabalVersion)

main :: IO ()
main =
  putStrLn $ if cabalVersion >= Version [1,22] []
             then "(\"-DuseCompilerInfo\")"
             else "()"

它不漂亮,但它有效。

0 个答案:

没有答案