Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 在没有CPP的情况下,如何最好地适应阴谋集团库中的类型变化?_Haskell_Emacs_Cabal_Flycheck - Fatal编程技术网

Haskell 在没有CPP的情况下,如何最好地适应阴谋集团库中的类型变化?

Haskell 在没有CPP的情况下,如何最好地适应阴谋集团库中的类型变化?,haskell,emacs,cabal,flycheck,Haskell,Emacs,Cabal,Flycheck,我想增强用户对从.cabal文件自动配置flycheck的支持 要进行此自动配置,flycheck使用的原始策略是读取.cabal文件并使用FlattPackageDescription。这很简单,但不考虑条件表达式,这可能会导致问题,例如,在使用较新版本的bytestring包时,不需要bytestring builder 要使用的适当界面似乎是finalizePackageDescription。这确实有效……但是它的类型签名在1.20和1.22之间发生了变化——现在,它不再使用Compil

我想增强用户对从.cabal文件自动配置flycheck的支持

要进行此自动配置,flycheck使用的原始策略是读取.cabal文件并使用
FlattPackageDescription
。这很简单,但不考虑条件表达式,这可能会导致问题,例如,在使用较新版本的
bytestring
包时,不需要
bytestring builder

要使用的适当界面似乎是
finalizePackageDescription
。这确实有效……但是它的类型签名在1.20和1.22之间发生了变化——现在,它不再使用
CompilerId
,而是使用
CompilerInfo
。不过,我希望在整个API更改过程中提供一致的支持

虽然解决方案通常是使用
CPP
宏,但这些宏是由
Cabal
本身提供的,
flycheck
只是使用
runhaskell
调用帮助文件,因此我们没有访问它们的权限

我能想到的唯一选择是创建另一个助手,首先获取
Cabal
版本信息,然后为
runhaskell
调用构造适当的
CPP
设置,这样我们就可以这样做。这应该行得通,但看起来像是个黑客

因此,我在这里寻找其他选项,使我能够支持两个版本的界面,而不必求助于
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

我所实施的——尽管我很乐意考虑一个更独立的选项---是一个助手,它吐出了<代码> DuseCompilerInfo <代码>(作为一个S- EXPR,因为我们正在处理Emacs),如果它是一个最新版本的阴谋:

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

main :: IO ()
main =
  putStrLn $ if cabalVersion >= Version [1,22] []
             then "(\"-DuseCompilerInfo\")"
             else "()"
然后使用该标志运行原始帮助程序,并有条件地导入新结构,并且在上面的case语句之前具有以下条件代码:

#ifdef useCompilerInfo
      buildCompilerId = unknownCompilerInfo (CompilerId buildCompilerFlavor compilerVersion) NoAbiTag
#else
      buildCompilerId = CompilerId buildCompilerFlavor compilerVersion
#endif

它并不漂亮,但很管用。

有人告诉我,这些技巧中有一些是由于指针才起作用的。不幸的是,我开始相信,他们引入了一种新的数据类型(CompilerInfo),这就不可行了。这真的很难看,但是,通过使用
mkName
构造所需的名称,您应该始终能够使用模板Haskell方法。博客文章中提到的其他方法是否有效,可能取决于您需要编写的两个版本的代码是什么;也许在你的问题中包括它们?