Различные импорты в зависимости от версии зависимостей
У меня есть модуль, который использует Control.Exception
в Base < 4
, который является Control.OldException
в Base >= 4
. Как я могу, используя cabal или любой другой инструмент, избавиться от зависимости версии (просто зависите от Base
и не Base < 4
) и импортировать Control.OldException
при использовании Base >= 4
и Control.Exception
при использовании Base < 4
?
3 ответа:
cabal
автоматически устанавливает определенные определения CPP на основе версии используемых пакетов.Поэтому для вашего случая я бы:
{-# LANGUAGE CPP #-} module Blah where #if MIN_VERSION_base(0,4,0) import Control.OldException #else import Control.Exception #endif
Этот метод прекрасно работает с Кабалом.
(на самом деле, я бы использовал новые исключения и не стал бы утруждать себя поддержкой базы
С Cabal это делается с помощью "флагов" и алгоритма решения ограничений. Пример (из control-monad-exception на 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
На машине с более старой версией
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)
.
Это языковой агностический ответ, поэтому он может не относиться к вам.
Есть пара вариантов
- оберните оба исключения в Суперэксцепцию, имеющую обе реализации. Дайте ему параметр, который говорит ему, какую реализацию использовать на основе
Base
.- исключение Рефактора, являющееся дочерним элементом OldException с переопределенными вызовами. (лучший вариант)