我为Alex做贡献,显然它取决于很多库,应该为很多版本编译。
我需要使用仅可从 GHC 7.6.1 获得的功能来更好地处理错误。所以我想使用#if ...
导入所述函数,否则,我会以不同的方式处理错误。
我见过一些:
#if __GLASGOW_HASKELL__ >= 610
import Control.Exception ( bracketOnError )
#endif
所以我做了:
#if __GLASGOW_HASKELL__ >= 761
import Text.Read ( readMaybe )
#endif
认为761
是GHC版本7.6.1
的别名,当我构建cabal包并试用它时,即使我使用,该功能也无法导入Glorious Glasgow Haskell编译系统,版本7.8.4 。
因此,在使用程序试用后,我发现7.8.1
在__GLASGOW_HASKELL__
中标识为708
。
{-# LANGUAGE CPP #-}
module Main where
#if __GLASGOW_HASKELL__ == 708
ver = "==708"
#else
ver = "/=708"
#endif
main = putStrLn $ ver
运行它:
$ runhaskell if.hs
==708
我怎么知道7.6.1
应该使用什么值,还是有更好的方法来解决这个问题?
答案 0 :(得分:14)
GHC的用户指南section 6.11.3.1中描述的内容:
对于GHC的版本
x.y.z
,__GLASGOW_HASKELL__
的值是整数⟨xyy⟩(如果⟨y⟩是单个数字,则添加前导零,例如在版本6.2中GHC,__GLASGOW_HASKELL__==602
)。有关详情,请参见GHC version numbering policy。
因此对于7.6.1
,您需要检查__GLASGOW_HASKELL__ >= 706
。原因是7.10.x
。
答案 1 :(得分:6)
对于GHC的xyz版本,
__GLASGOW_HASKELL__
的值是整数xyy(如果y是单个数字,则添加前导零,因此例如在GHC版本6.2中,__GLASGOW_HASKELL__
== 602)。更多信息,请参见第1.4节“GHC版本编号策略”。运气好的话,在支持C风格预处理的所有其他实现中,
__GLASGOW_HASKELL__
将不会被定义。(供参考:其他系统的可比较符号为:{0}为Hugs,
__HUGS__
为nhc98,__NHC__
为hbc。)NB。在预处理Haskell源和C源时设置此宏,包括从Haskell模块生成的C源(即.hs,.lhs,.c和.hc文件)。
答案 2 :(得分:5)
正如Daniel Wagner所说,检查包版本的最正确方法通常是使用Cabal MIN_VERSION
宏。例如,您可以使用
#if MIN_VERSION_base(4,6,0)
确定base
包是否至少是4.6.0版本,这是您所寻找功能的最早版本。
base
包有点奇怪。它由GHC和现已解散的Hugs和NHC实施使用。然后使用Cabal宏以更便携的方式检查base
版本。目前,GHC是唯一一个使用base
的人,因此可移植性论点不太清楚,但这种方法还有检查主要和次要版本号的优势。
由于base
版本与GHC版本紧密相关,因此您可以使用MIN_VERSION_base
来估算{{1版本。当前的__GLASGOW_HASKELL__
头部有条件地定义了这种后退。
从GHC 8开始,编译器本身已经接管了定义base
宏的工作。这很棒,因为无论是否使用Cabal构建,您现在都可以使用这些宏。没有更丑陋的近似值!