I have a module that uses Control.Ex开发者_C百科ception
in Base < 4
which is Control.OldException
in Base >= 4
. How can I, using cabal or any other tool, get rid of the version dependency (just depend on Base
and not Base < 4
) and import Control.OldException
when using Base >= 4
and Control.Exception
when using Base < 4
?
cabal
automatically sets certain CPP definitions based on the version of packages used.
So for your case I would:
{-# LANGUAGE CPP #-}
module Blah where
#if MIN_VERSION_base(0,4,0)
import Control.OldException
#else
import Control.Exception
#endif
This method builds fine with cabal.
(actually, I would use new exceptions and wouldn't bother supporting base < 4, but that's just me)
With Cabal this is done with "flags" and its constraint solving algorithm. An example (from control-monad-exception on Hackage):
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
On a machine with an older version of base
, Cabal will try to solve the dependency with extensibleExceptions False
, fail, then retry with it True
and use the different build-depends
, which will succeed. (You can also turn the flag on from the command line.)
http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#configurations documents this mechanism, and the rest of the page describes other mechanisms including direct conditionals such as if impl(ghc >= 6.10.0)
.
This is a language agnostic answer, so it may not apply for you.
There's a couple options
- Wrap both exceptions in a SuperException that has both implementations. Give it a parameter that tells it what implementation to use based on
Base
. - Refactor Exception to be a child of OldException with overriden calls. (best option)
精彩评论