4

我有一个Control.ExceptionBase < 4其中使用Control.OldException的模块Base >= 4。我如何使用 cabal 或任何其他工具摆脱版本依赖(仅依赖Base和不依赖)并在使用时和使用时Base < 4导入?Control.OldExceptionBase >= 4Control.ExceptionBase < 4

4

3 回答 3

8

cabal 根据使用的软件包版本自动设置某些 CPP 定义。

所以对于你的情况,我会:

{-# LANGUAGE CPP #-}
module Blah where
#if MIN_VERSION_base(0,4,0)
import Control.OldException
#else
import Control.Exception
#endif

这种方法在 cabal 中构建得很好。

(实际上,我会使用新的异常并且不会费心支持 base < 4,但这只是我)

于 2011-04-03T17:26:41.610 回答
1

使用 Cabal,这是通过“标志”及其约束求解算法完成的。一个例子(来自Hackage上的control-monad-exception):

Flag extensibleExceptions
  description: Use extensible-exception package
  default: False

(...)

  if flag(extensibleExceptions)
    build-depends:
      extensible-exceptions >= 0.1 && <0.2,
      base >= 3.0 && <4
  else
    build-depends:
      base >= 4 && < 5

在具有旧版本的机器上base,Cabal 将尝试使用 解决依赖关系extensibleExceptions False,失败,然后使用它重试True并使用不同的build-depends,这将成功。(您也可以从命令行打开标志。)

http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#configurations记录了这个机制,页面的其余部分描述了其他机制,包括直接条件,例如if impl(ghc >= 6.10.0).

于 2011-04-03T17:38:17.467 回答
-1

这是一个与语言无关的答案,因此它可能不适用于您。

有几个选择

  1. 将两个异常都包装在具有这两种实现的 SuperException 中。给它一个参数,告诉它基于Base.
  2. 将 Exception 重构为具有覆盖调用的 OldException 的子级。(最佳选择)
于 2011-04-03T17:23:27.270 回答