diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -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
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.markdown
@@ -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
diff --git a/data-interval.cabal b/data-interval.cabal
--- a/data-interval.cabal
+++ b/data-interval.cabal
@@ -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
 
diff --git a/src/Data/Interval.hs b/src/Data/Interval.hs
--- a/src/Data/Interval.hs
+++ b/src/Data/Interval.hs
@@ -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
diff --git a/test/TestInterval.hs b/test/TestInterval.hs
--- a/test/TestInterval.hs
+++ b/test/TestInterval.hs
@@ -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
