[英]Why does this code that type-checked in GHC 7.10 no longer type check in GHC 8.0.1?
[英]GHC version check in code
我正在为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
应该使用什么值,还是有更好的方法来解决这个问题?
这在GHC用户指南的第6.11.3.1节中有所描述:
对于GHC的
xyz
版本,__GLASGOW_HASKELL__
的值是整数⟨xyy⟩(如果⟨y⟩是单个数字,则添加前导零,因此例如在GHC的版本6.2中,__GLASGOW_HASKELL__==602
)。 有关GHC版本编号策略的更多信息。
因此对于7.6.1
,您将检查__GLASGOW_HASKELL__ >= 706
。 原因是7.10.x
这样的版本。
阅读精美的文档 :
对于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文件)。
正如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
以便在没有Cabal的情况下进行编译,使用__GLASGOW_HASKELL__
来估算base
版本。 当前的containers
头部有条件地限定了这种后退。
从GHC 8开始,编译器本身已经接管了定义MIN_VERSION
宏的工作。 这很棒,因为无论是否使用Cabal构建,您现在都可以使用这些宏。 没有更丑陋的近似!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.