Различный импорт в зависимости от версии зависимостей - PullRequest
4 голосов
/ 03 апреля 2011

У меня есть модуль, который использует Control.Exception в Base < 4, что Control.OldException в Base >= 4.Как я могу, используя cabal или любой другой инструмент, избавиться от зависимости от версии (зависит только от Base, а не Base < 4) и импортировать Control.OldException при использовании Base >= 4 и Control.Exception при использовании Base < 4?

Ответы [ 3 ]

8 голосов
/ 03 апреля 2011

cabal автоматически устанавливает определенные определения CPP на основе версии используемых пакетов.

Так что для вашего случая я бы:

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

Этот метод создаетхорошо с cabal.

(на самом деле, я бы использовал новые исключения и не стал бы беспокоиться о поддержке базы <4, но это только я) </p>

1 голос
/ 03 апреля 2011

С Cabal это делается с помощью «флагов» и алгоритма решения его ограничений. Пример (из 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

На машине с более старой версией 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).

0 голосов
/ 03 апреля 2011

Это независимый от языка ответ, поэтому он может к вам не относиться.

Есть несколько вариантов

  1. Обернуть оба исключения в SuperException, который имеет обе реализации. Дайте ему параметр, который говорит ему, какую реализацию использовать на основе Base.
  2. Refactor Exception, чтобы быть потомком OldException с переопределенными вызовами. (лучший вариант)
...