Cabal-syntax- A library for working with .cabal files
Safe HaskellNone



This module implements a view of a VersionRange as a finite list of separated version intervals.

In conversion from and to VersionRange it makes some effort to preserve the caret operator ^>=x.y. This constraint a priori specifies the same interval as ==x.y.*, but indicates that newer versions could be acceptable (allow-newer: ^).


Version intervals

data VersionIntervals Source #

A complementary representation of a VersionRange. Instead of a boolean version predicate it uses an increasing sequence of non-overlapping, non-empty intervals.

The key point is that this representation gives a canonical representation for the semantics of VersionRanges. This makes it easier to check things like whether a version range is empty, covers all versions, or requires a certain minimum or maximum version. It also makes it easy to check equality or containment. It also makes it easier to identify 'simple' version predicates for translation into foreign packaging systems that do not support complex version range expressions.

unVersionIntervals :: VersionIntervals -> [VersionInterval] Source #

Inspect the list of version intervals.


toVersionIntervals :: VersionRange -> VersionIntervals Source #

Convert a VersionRange to a sequence of version intervals.

fromVersionIntervals :: VersionIntervals -> VersionRange Source #

Convert a VersionIntervals value back into a VersionRange expression representing the version intervals.


normaliseVersionRange2 :: VersionRange -> VersionRange Source #

Since Cabal-3.6 this function.. TODO


Version intervals view

asVersionIntervals :: VersionRange -> [VersionInterval] Source #

View a VersionRange as a union of intervals.

This provides a canonical view of the semantics of a VersionRange as opposed to the syntax of the expression used to define it. For the syntactic view use foldVersionRange.

Each interval is non-empty. The sequence is in increasing order and no intervals overlap or touch. Therefore only the first and last can be unbounded. The sequence can be empty if the range is empty (e.g. a range expression like && 2).

Other checks are trivial to implement using this view. For example:

isNoVersion vr | [] <- asVersionIntervals vr = True
               | otherwise                   = False
isSpecificVersion vr
   | [(LowerBound v  InclusiveBound
      ,UpperBound v' InclusiveBound)] <- asVersionIntervals vr
   , v == v'   = Just v
   | otherwise = Nothing

data Bound Source #


Instances details
Show Bound Source # 
Instance details

Defined in Distribution.Types.VersionInterval

Eq Bound Source # 
Instance details

Defined in Distribution.Types.VersionInterval


(==) :: Bound -> Bound -> Bool #

(/=) :: Bound -> Bound -> Bool #


invariantVersionIntervals :: VersionIntervals -> Bool Source #

VersionIntervals invariant:

  • all intervals are valid (lower bound is less then upper bound, i.e. non-empty)
  • intervals doesn't touch each other (distinct)