2

假设你有一个你知道是安全的模块。

您想使用{-# LANGUAGE Safe #-}模块本身或Extensions: Safecabal 文件中的内容将其标记为 Safe Haskell。不幸的是,做这些中的任何一个都会破坏向后兼容性(即模块不会建立在 GHC < 7.2 上)。

如果整个库是安全的,您可以像这样将扩展指令包装在 cabal 文件中:

if impl(ghc >= 7.2)
  Extensions: Safe

但这仅适用于整个图书馆。

如何以向后兼容的方式将单个模块标记为 Safe Haskell?

4

2 回答 2

5

如果您不需要支持早于 6.12 的 GHC 版本(6.12.3 是我测试过的最古老的构造),您可以使用预处理器来完成,

{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Safe #-}
#endif

或者,您可以使用.cabal文件中的标志来选择要包含的源文件。

{-# LANGUAGE #-}¹ 对于ghc -6.12 ,必须#if在.#if#if

于 2012-06-23T18:17:13.500 回答
2

您可以编写模块的两个版本,并在编译时在它们之间进行选择。例如:

-- has-safe/Foo.hs
{-# LANGUAGE CPP #-}
foo = 3

-- no-safe/Foo.hs
{-# LANGUAGE CPP, Safe #-}
foo = 3

-- foo.cabal
if impl(ghc >= 7)
    hs-source-dirs: has-safe
else
    hs-source-dirs: no-safe

CPP与基于 - 的方法相比,这种方法有优点和缺点。主要优点是您拥有阴谋集团支持的所有条件以供您选择。主要缺点是您现在有两个文件要保持同步。(但是,这应该特别容易自动化:类似于

echo {-# LANGUAGE Safe #-} > has-safe/Foo.hs
cat no-safe/Foo.hs >> has-safe/Foo.hs

在每次编辑之后no-safe/Foo.hs应该可以解决问题,并且可以通过各种方式自动化。)

于 2012-06-23T19:49:11.070 回答