[英]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.