range 0.1.0.1 → 0.1.1.0
raw patch · 6 files changed
+39/−6 lines, 6 filesdep ~QuickCheckPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: QuickCheck
API changes (from Hackage documentation)
+ Data.Range.Range: difference :: (Ord a, Enum a) => [Range a] -> [Range a] -> [Range a]
+ Data.Range.RangeTree: RangeDifference :: RangeOperation
Files
- Data/Range/Data.hs +1/−0
- Data/Range/Range.hs +12/−0
- Data/Range/RangeInternal.hs +3/−0
- Data/Range/RangeTreeInternal.hs +1/−0
- Test/Range.hs +17/−3
- range.cabal +5/−3
Data/Range/Data.hs view
@@ -16,6 +16,7 @@ data RangeOperation = RangeUnion -- ^ Represents the set union operation. | RangeIntersection -- ^ Represents the set intersection operation.+ | RangeDifference -- ^ Represents the set difference operation. -- | A Range Tree is a construct that can be built and then efficiently evaluated so that -- you can compress an entire tree of operations on ranges into a single range quickly.
Data/Range/Range.hs view
@@ -9,6 +9,7 @@ invert, union, intersection,+ difference, fromRanges ) where @@ -20,15 +21,25 @@ -- ranges. union :: (Ord a, Enum a) => [Range a] -> [Range a] -> [Range a] union a b = exportRangeMerge $ unionRangeMerges (loadRanges a) (loadRanges b)+{-# INLINE union #-} -- | Performs a set intersection between the two input ranges and returns the resultant set of -- ranges. intersection :: (Ord a, Enum a) => [Range a] -> [Range a] -> [Range a] intersection a b = exportRangeMerge $ intersectionRangeMerges (loadRanges a) (loadRanges b)+{-# INLINE intersection #-} +-- | Performs a set difference between the two input ranges and returns the resultant set of+-- ranges.+difference :: (Ord a, Enum a) => [Range a] -> [Range a] -> [Range a]+difference a b = exportRangeMerge $ intersectionRangeMerges a' (invertRM b')+ where a' = loadRanges a+ b' = loadRanges b+ -- | An inversion function, given a set of ranges it returns the inverse set of ranges. invert :: (Ord a, Enum a) => [Range a] -> [Range a] invert = exportRangeMerge . invertRM . loadRanges+{-# INLINE invert #-} -- | A check to see if two ranges overlap. If they do then true is returned; false -- otherwise.@@ -69,6 +80,7 @@ -- this is redundant: mergeRanges . intersection mergeRanges :: (Ord a, Enum a) => [Range a] -> [Range a] mergeRanges = exportRangeMerge . loadRanges+{-# INLINE mergeRanges #-} -- | A set of ranges represents a collection of real values without actually instantiating -- those values. This allows you to have infinite ranges. However, sometimes you wish to
Data/Range/RangeInternal.hs view
@@ -39,6 +39,7 @@ loadRanges :: (Ord a, Enum a) => [Range a] -> RangeMerge a loadRanges = storeRanges emptyRangeMerge+{-# INLINE[0] loadRanges #-} exportRangeMerge :: (Ord a, Enum a) => RangeMerge a -> [Range a] exportRangeMerge IRM = [InfiniteRange]@@ -55,6 +56,8 @@ simplifySpan (x, y) = if x == y then SingletonRange x else SpanRange x y++{-# RULES "load/export" [1] forall x. loadRanges (exportRangeMerge x) = x #-} intersectSpansRM :: (Ord a) => RangeMerge a -> RangeMerge a -> RangeMerge a intersectSpansRM one two = RM Nothing Nothing newSpans
Data/Range/RangeTreeInternal.hs view
@@ -7,6 +7,7 @@ evaluateRangeTree (RangeNode operation left right) = case operation of RangeUnion -> leftEval `unionRangeMerges` rightEval RangeIntersection -> leftEval `intersectionRangeMerges` rightEval+ RangeDifference -> leftEval `intersectionRangeMerges` (invertRM rightEval) where leftEval = evaluateRangeTree left rightEval = evaluateRangeTree right
Test/Range.hs view
@@ -17,7 +17,7 @@ data UnequalPair a = UnequalPair (a, a) deriving (Show) -instance (Num a, Eq a) => Arbitrary (UnequalPair a) where+instance (Integral a, Num a, Eq a) => Arbitrary (UnequalPair a) where arbitrary = do first <- arbitrarySizedIntegral second <- arbitrarySizedIntegral `suchThat` (/= first)@@ -32,7 +32,7 @@ data SpanContains a = SpanContains (a, a) a deriving (Show) -instance (Num a, Ord a, Random a) => Arbitrary (SpanContains a) where+instance (Num a, Integral a, Ord a, Random a) => Arbitrary (SpanContains a) where arbitrary = do begin <- arbitrarySizedIntegral end <- arbitrarySizedIntegral `suchThat` (>= begin)@@ -52,7 +52,7 @@ , testProperty "infinite ranges contain everything" prop_infinite_range_contains_everything ] -instance (Num a, Ord a, Enum a) => Arbitrary (Range a) where+instance (Num a, Integral a, Ord a, Enum a) => Arbitrary (Range a) where arbitrary = oneof [ generateSingleton , generateSpan@@ -104,6 +104,15 @@ actual = map (inRanges intersectedRanges) points expected = zipWith (&&) before_a before_b +prop_elements_before_difference_and_not_true :: ([Integer], [Range Integer], [Range Integer]) -> Bool+prop_elements_before_difference_and_not_true (points, a, b) = actual == expected+ where+ before_a = map (inRanges a) points+ before_b = map (inRanges b) points+ diffedRanges = a `difference` b+ actual = map (inRanges diffedRanges) points+ expected = zipWith (&&) before_a $ map not before_b+ test_union = testGroup "union function properties" [ testProperty "Unions from before OR together and continue to work" prop_elements_before_union_or_true ]@@ -112,12 +121,17 @@ [ testProperty "Intersection before AND's to after" prop_elements_before_intersection_and_true ] +test_difference = testGroup "difference function properties"+ [ testProperty "Difference before AND/NOT's to after" prop_elements_before_difference_and_not_true+ ]+ --tests :: [Test] tests = [ tests_inRange , test_ranges_invert , test_union , test_intersection+ , test_difference ] ++ rangeMergeTestCases
range.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.1.0.1+version: 0.1.1.0 -- A short (one-line) description of the package. synopsis: This has a bunch of code for specifying and managing ranges in your code.@@ -22,6 +22,8 @@ trivial for you to do so. It also attempts to do so in the most efficient way possible. +homepage: https://bitbucket.org/robertmassaioli/range+ -- The license under which the package is released. license: MIT @@ -73,8 +75,8 @@ main-is: Test/Range.hs build-depends: base >= 4.5 && < 5 , Cabal >= 1.14- , QuickCheck >= 2.4.0.1 && < 2.6+ , QuickCheck >= 2.4.0.1 && < 3 , test-framework-quickcheck2 >= 0.2 && < 0.4 , test-framework >= 0.4 && < 0.9 , random >= 1.0- ghc-options: -rtsopts -Wall+ ghc-options: -rtsopts -Wall -fno-enable-rewrite-rules