GHC版本检入代码

cha*_*ni2 12 haskell ghc

我正在为Alex做贡献,它显然取决于很多库,应该编译很多版本.

我需要使用一个只能从GHC 7.6.1获得的函数来更好地处理错误.所以我想使用an #if ...来导入所述函数,否则,我会以不同的方式处理错误.

我见过一些:

#if __GLASGOW_HASKELL__ >= 610
import Control.Exception ( bracketOnError )
#endif
Run Code Online (Sandbox Code Playgroud)

所以我做了:

#if __GLASGOW_HASKELL__ >= 761
import Text.Read ( readMaybe )
#endif
Run Code Online (Sandbox Code Playgroud)

认为这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
Run Code Online (Sandbox Code Playgroud)

运行它:

$ runhaskell if.hs
==708
Run Code Online (Sandbox Code Playgroud)

我怎么知道我应该使用什么价值7.6.1,或者有更好的方法来解决这个问题?

Zet*_*eta 15

这在GHC用户指南的第6.11.3.1节中有所描述:

对于x.y.zGHC的版本,值__GLASGOW_HASKELL__是整数⟨xyy⟩(如果⟨y⟩是单个数字,则添加前导零,例如在GHC版本6.2中__GLASGOW_HASKELL__==602).有关GHC版本编号策略的更多信息.

所以7.6.1,你会检查__GLASGOW_HASKELL__ >= 706.原因是这样的版本7.10.x.

  • @ chamini2如果你想依赖一个版本的基础,你应该这样做,而不是取决于GHC的版本.使用cabal的MIN_VERSION系列宏(再次阅读精细文档以了解有关它们如何工作的更多信息). (2认同)

Dan*_*ner 6

阅读精美的文档:

对于GHC的版本xyz,值__GLASGOW_HASKELL__是整数xyy(如果y是单个数字,则添加前导零,因此例如在GHC的版本6.2中,__GLASGOW_HASKELL__== 602).有关详细信息,请参见第1.4节"GHC版本编号策略".

运气好的话,__GLASGOW_HASKELL__在支持C风格预处理的所有其他实现中都是未定义的.

(供参考:其他系统的可比符号为:__HUGS__对于Hugs,__NHC__对于nhc98和__HBC__对于hbc.)

NB.在预处理Haskell源和C源时设置此宏,包括从Haskell模块生成的C源(即.hs,.lhs,.c和.hc文件).


dfe*_*uer 6

正如Daniel Wagner所指出的,检查包版本的最正确方法通常是使用Cabal MIN_VERSION宏.例如,你可以使用

#if MIN_VERSION_base(4,6,0)
Run Code Online (Sandbox Code Playgroud)

确定base软件包是否至少是4.6.0版本,这是您使用的功能最早的版本.

base软件包是一个有点怪异.它由GHC和现已解散的Hugs和NHC实施使用.然后使用Cabal宏以更便携的方式检查base版本.目前,GHC是唯一使用的base,因此可移植性论点不太明确,但该方法还具有检查主要版本号和次要版本号的优势.

由于base版本与GHC版本紧密相关,因此您可以MIN_VERSION_base使用__GLASGOW_HASKELL__估算base版本来定义合理的后备形式,以便在没有Cabal的情况下进行编译.当前的containers头部有条件地定义了这种后退.

更新

从GHC 8开始,编译器本身已经接管了定义MIN_VERSION宏的工作.这很棒,因为无论是否使用Cabal构建,您现在都可以使用这些宏.没有更丑陋的近似!