GHC版本检入代码

时间:2015-02-03 06:11:21

标签: haskell ghc

我为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应该使用什么值,还是有更好的方法来解决这个问题?

3 个答案:

答案 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)

阅读fine documentation

  

对于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构建,您现在都可以使用这些宏。没有更丑陋的近似值!