data-interval 0.5.0 → 0.6.0
raw patch · 5 files changed
+159/−33 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.Interval: instance Typeable EndPoint
- Data.Interval: instance Typeable Interval
+ Data.Interval: hulls :: (Ord r, Num r) => [Interval r] -> Interval r
+ Data.Interval: instance Typeable1 EndPoint
+ Data.Interval: instance Typeable1 Interval
+ Data.Interval: intersections :: (Ord r, Num r) => [Interval r] -> Interval r
Files
- .travis.yml +56/−1
- CHANGELOG.markdown +12/−0
- data-interval.cabal +2/−10
- src/Data/Interval.hs +19/−22
- test/TestInterval.hs +70/−0
.travis.yml view
@@ -1,1 +1,56 @@-language: haskell+# NB: don't set `language: haskell` here++# The following enables several GHC versions to be tested; often it's enough to test only against the last release in a major GHC version. Feel free to omit lines listings versions you don't need/want testing for.+env:+# - GHCVER=6.12.3+# - GHCVER=7.0.1+# - GHCVER=7.0.2+# - GHCVER=7.0.3+# - GHCVER=7.0.4+# - GHCVER=7.2.1+# - GHCVER=7.2.2+# - GHCVER=7.4.1+# - GHCVER=7.4.2+# - GHCVER=7.6.1+# - GHCVER=7.6.2+ - GHCVER=7.6.3+# - GHCVER=7.8.1 # see note about Alex/Happy+# - GHCVER=7.8.2 # see note about Alex/Happy+ - GHCVER=7.8.3 # see note about Alex/Happy+# - GHCVER=head # see section about GHC HEAD snapshots++# Note: the distinction between `before_install` and `install` is not important.+before_install:+ - travis_retry sudo add-apt-repository -y ppa:hvr/ghc+ - travis_retry sudo apt-get update+ - travis_retry sudo apt-get install cabal-install-1.18 ghc-$GHCVER # see note about happy/alex+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/1.18/bin:$PATH+ - |+ if [ $GHCVER = "head" ] || [ ${GHCVER%.*} = "7.8" ]; then+ travis_retry sudo apt-get install happy-1.19.3 alex-3.1.3+ export PATH=/opt/alex/3.1.3/bin:/opt/happy/1.19.3/bin:$PATH+ else+ travis_retry sudo apt-get install happy alex+ fi++install:+ - cabal update+ - cabal install --only-dependencies --enable-tests -v2 # -v2 provides useful information for debugging++# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.+script:+ - cabal configure --enable-tests -v2 # -v2 provides useful information for debugging+ - cabal build # this builds all libraries and executables (including tests/benchmarks)+ - cabal test+ - cabal check+ - cabal sdist # tests that a source-distribution can be generated++# The following scriptlet checks that the resulting source distribution can be built & installed+ - export SRC_TGZ=$(cabal-1.18 info . | awk '{print $2 ".tar.gz";exit}') ;+ cd dist/;+ if [ -f "$SRC_TGZ" ]; then+ cabal install "$SRC_TGZ";+ else+ echo "expected '$SRC_TGZ' not found";+ exit 1;+ fi
+ CHANGELOG.markdown view
@@ -0,0 +1,12 @@+0.6.0+-----+* add hulls, intersections :: (Num r, Ord r) => [Interval r] -> Interval r+* fix a bug of (<=?) operator++0.5.0+-----+* fix dependency issue with QuickCheck and test-framework-quickcheck2++0.4.0+-----+* add simplestRationalWithin :: RealFrac r => Interval r -> Maybe Rational
data-interval.cabal view
@@ -1,5 +1,5 @@ Name: data-interval-Version: 0.5.0+Version: 0.6.0 License: BSD3 License-File: COPYING Author: Masahiro Sakai (masahiro.sakai@gmail.com)@@ -11,19 +11,11 @@ Unlike the intervals package (<http://hackage.haskell.org/package/intervals>), this package provides both open and closed intervals and is intended to be used with Rational.- .- Changes in 0.5.0- .- * fix dependency issue with QuickCheck and test-framework-quickcheck2- .- Changes in 0.4.0- .- * add simplestRationalWithin :: RealFrac r => Interval r -> Maybe Rational- Bug-Reports: https://github.com/msakai/data-interval/issues Extra-Source-Files: README.md COPYING+ CHANGELOG.markdown .travis.yml Build-Type: Simple
src/Data/Interval.hs view
@@ -1,3 +1,4 @@+{-# OPTIONS_GHC -Wall #-} {-# LANGUAGE ScopedTypeVariables, DeriveDataTypeable, DoAndIfThenElse #-} ----------------------------------------------------------------------------- -- |@@ -54,7 +55,9 @@ -- * Combine , intersection+ , intersections , hull+ , hulls -- * Operations , pickup@@ -119,7 +122,7 @@ instance (Num r, Ord r) => BoundedLattice (Interval r) instance (Num r, Ord r, Show r) => Show (Interval r) where- showsPrec p x | null x = showString "empty"+ showsPrec _ x | null x = showString "empty" showsPrec p x = showParen (p > appPrec) $ showString "interval " . showsPrec appPrec1 (lowerBound' x) .@@ -227,6 +230,10 @@ GT -> in2 ) +-- | intersection of a list of intervals.+intersections :: (Ord r, Num r) => [Interval r] -> Interval r+intersections xs = foldl' intersection whole xs+ -- | convex hull of two intervals hull :: forall r. (Ord r, Num r) => Interval r -> Interval r -> Interval r hull x1 x2@@ -251,6 +258,10 @@ GT -> in2 ) +-- | convex hull of a list of intervals.+hulls :: (Ord r, Num r) => [Interval r] -> Interval r+hulls xs = foldl' hull empty xs+ -- | Is the interval empty? null :: Ord r => Interval r -> Bool null (Interval (x1,in1) (x2,in2)) = @@ -298,7 +309,7 @@ -- | pick up an element from the interval if the interval is not empty. pickup :: (Real r, Fractional r) => Interval r -> Maybe r-pickup (Interval (NegInf,in1) (PosInf,in2)) = Just 0+pickup (Interval (NegInf,_) (PosInf,_)) = Just 0 pickup (Interval (Finite x1, in1) (PosInf,_)) = Just $ if in1 then x1 else x1+1 pickup (Interval (NegInf,_) (Finite x2, in2)) = Just $ if in2 then x2 else x2-1 pickup (Interval (Finite x1, in1) (Finite x2, in2)) =@@ -306,7 +317,7 @@ GT -> Nothing LT -> Just $ (x1+x2) / 2 EQ -> if in1 && in2 then Just x1 else Nothing-pickup x = Nothing+pickup _ = Nothing -- | 'simplestRationalWithin' returns the simplest rational number within the interval. -- A rational number @y@ is said to be /simpler/ than another @y'@ if@@ -349,7 +360,7 @@ case ub_a of NegInf -> True -- a is empty, so it holds vacuously PosInf -> True -- b is empty, so it holds vacuously- Finite x -> not (in1 && in2)+ Finite _ -> not (in1 && in2) where (ub_a, in1) = upperBound' a (lb_b, in2) = lowerBound' b@@ -386,8 +397,8 @@ EQ -> case lb_a of NegInf -> False -- b is empty- PosInf -> True -- a is empty- Finite x -> in1 && in2+ PosInf -> False -- a is empty+ Finite _ -> in1 && in2 where (lb_a, in1) = lowerBound' a (ub_b, in2) = upperBound' b@@ -481,9 +492,9 @@ maxBound = PosInf instance Functor EndPoint where- fmap f NegInf = NegInf+ fmap _ NegInf = NegInf fmap f (Finite x) = Finite (f x)- fmap f PosInf = PosInf+ fmap _ PosInf = PosInf instance NFData r => NFData (EndPoint r) where rnf (Finite x) = rnf x@@ -555,17 +566,3 @@ recipEndPoint PosInf = Finite 0 recipEndPoint NegInf = Finite 0 recipEndPoint (Finite x) = Finite (1/x)---- | Combining two @Maybe@ values using given function.-combineMaybe :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a-combineMaybe _ Nothing y = y-combineMaybe _ x Nothing = x-combineMaybe f (Just x) (Just y) = Just (f x y)---- | is the number integral?------ @--- isInteger x = fromInteger (round x) == x--- @-isInteger :: RealFrac a => a -> Bool-isInteger x = fromInteger (round x) == x
test/TestInterval.hs view
@@ -104,6 +104,16 @@ (Interval.intersection a b == a) == Interval.isSubsetOf a b +case_intersections_empty_list = Interval.intersections [] @?= Interval.whole++prop_intersections_singleton_list =+ forAll intervals $ \a -> Interval.intersections [a] == a++prop_intersections_two_elems =+ forAll intervals $ \a ->+ forAll intervals $ \b ->+ Interval.intersections [a,b] == Interval.intersection a b+ {-------------------------------------------------------------------- Hull --------------------------------------------------------------------}@@ -143,6 +153,16 @@ (Interval.hull a b == b) == Interval.isSubsetOf a b +case_hulls_empty_list = Interval.hulls [] @?= Interval.empty++prop_hulls_singleton_list =+ forAll intervals $ \a -> Interval.hulls [a] == a++prop_hulls_two_elems =+ forAll intervals $ \a ->+ forAll intervals $ \b ->+ Interval.hulls [a,b] == Interval.hull a b+ {-------------------------------------------------------------------- member --------------------------------------------------------------------}@@ -318,6 +338,10 @@ forAll arbitrary $ \a -> Interval.singleton (a::Rational) <=! Interval.singleton a +prop_eq_all_singleton =+ forAll arbitrary $ \a ->+ Interval.singleton (a::Rational) ==! Interval.singleton a+ prop_lt_some_singleton = forAll arbitrary $ \a -> forAll arbitrary $ \b ->@@ -335,6 +359,52 @@ prop_le_some_singleton_2 = forAll arbitrary $ \a -> Interval.singleton (a::Rational) <=? Interval.singleton a++prop_eq_some_singleton =+ forAll arbitrary $ \a ->+ Interval.singleton (a::Rational) ==? Interval.singleton a++prop_lt_all_empty =+ forAll intervals $ \a -> a <! Interval.empty++prop_lt_all_empty_2 =+ forAll intervals $ \a -> Interval.empty <! a++prop_le_all_empty =+ forAll intervals $ \a -> a <=! Interval.empty++prop_le_all_empty_2 =+ forAll intervals $ \a -> Interval.empty <=! a++prop_eq_all_empty =+ forAll intervals $ \a -> a ==! Interval.empty++prop_lt_some_empty =+ forAll intervals $ \a -> not (a <? Interval.empty)++prop_lt_some_empty_2 =+ forAll intervals $ \a -> not (Interval.empty <? a)++prop_le_some_empty =+ forAll intervals $ \a -> not (a <=? Interval.empty)++prop_le_some_empty_2 =+ forAll intervals $ \a -> not (Interval.empty <=? a)++prop_eq_some_empty =+ forAll intervals $ \a -> not (a ==? Interval.empty)++prop_intersect_le_some =+ forAll intervals $ \a -> + forAll intervals $ \b -> + not (Interval.null (Interval.intersection a b))+ ==> a <=? b++prop_intersect_eq_some =+ forAll intervals $ \a -> + forAll intervals $ \b -> + not (Interval.null (Interval.intersection a b))+ ==> a ==? b {-------------------------------------------------------------------- Num