diff --git a/data-interval.cabal b/data-interval.cabal
--- a/data-interval.cabal
+++ b/data-interval.cabal
@@ -1,16 +1,16 @@
 Name:		data-interval
-Version:	0.2.0
+Version:	0.3.0
 License:	BSD3
 License-File:	COPYING
 Author:		Masahiro Sakai (masahiro.sakai@gmail.com)
 Maintainer:	masahiro.sakai@gmail.com
-Category:	Data
-Cabal-Version:	>= 1.8
-Synopsis:	Interval Arithmetic
+Category:	Data, Math
+Cabal-Version:	>= 1.10
+Synopsis:	Interval arithmetic for both open and closed intervals
 Description:
    Unlike the intervals package (<http://hackage.haskell.org/package/intervals>),
-   this module provides both open and closed intervals and is intended to be used
-   with @Rational@.
+   this package provides both open and closed intervals and is intended to be used
+   with Rational.
 Bug-Reports:	https://github.com/msakai/data-interval/issues
 Extra-Source-Files:
    README.md
@@ -25,11 +25,10 @@
 Library
   Hs-source-dirs: src
   Build-Depends:
-     base >=4 && <5, lattices >=1.2.1.1, deepseq
-  Extensions:
+     base >=4 && <5, lattices >=1.2.1.1, deepseq, hashable >=1.1.2.5 && <1.3
+  Default-Language: Haskell2010
+  Other-Extensions:
      ScopedTypeVariables
-     FlexibleInstances
-     MultiParamTypeClasses
      DeriveDataTypeable
   Exposed-Modules:
      Data.Interval
@@ -39,4 +38,6 @@
   HS-Source-Dirs:    test
   Main-is:           TestInterval.hs
   Build-depends:     base >=4 && <5, containers, data-interval, test-framework, test-framework-th, test-framework-hunit, test-framework-quickcheck2, HUnit, QuickCheck >=2 && <3
-  Extensions: TemplateHaskell, DoAndIfThenElse
+  Default-Language: Haskell2010
+  Other-Extensions: TemplateHaskell
+
diff --git a/src/Data/Interval.hs b/src/Data/Interval.hs
--- a/src/Data/Interval.hs
+++ b/src/Data/Interval.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ScopedTypeVariables, FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable #-}
+{-# LANGUAGE ScopedTypeVariables, DeriveDataTypeable #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Interval
@@ -7,13 +7,17 @@
 -- 
 -- Maintainer  :  masahiro.sakai@gmail.com
 -- Stability   :  provisional
--- Portability :  non-portable (ScopedTypeVariables, FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable)
+-- Portability :  non-portable (ScopedTypeVariables, DeriveDataTypeable)
 --
 -- Interval datatype and interval arithmetic.
 --
 -- Unlike the intervals package (<http://hackage.haskell.org/package/intervals>),
 -- this module provides both open and closed intervals and is intended to be used
--- with @Rational@.
+-- with 'Rational'.
+--
+-- For the purpose of abstract interpretation, it might be convenient to use
+-- 'Lattice' instance. See also lattices package
+-- (<http://hackage.haskell.org/package/lattices>).
 -- 
 -----------------------------------------------------------------------------
 module Data.Interval
@@ -60,6 +64,8 @@
 import Control.DeepSeq
 import Control.Exception (assert)
 import Control.Monad hiding (join)
+import Data.Data
+import Data.Hashable
 import Data.List hiding (null)
 import Data.Maybe
 import Data.Monoid
@@ -78,17 +84,22 @@
 upperBound :: Num r => Interval r -> EndPoint r
 upperBound (Interval _ (ub,_)) = ub
 
--- | Lower bound of the interval and whether it is included in the interval
+-- | Lower bound of the interval and whether it is included in the interval.
+-- The result is convenient to use as an argument for 'interval'.
 lowerBound' :: Num r => Interval r -> (EndPoint r, Bool)
 lowerBound' (Interval lb _) = lb
 
--- | Upper bound of the interval and whether it is included in the interval
+-- | Upper bound of the interval and whether it is included in the interval.
+-- The result is convenient to use as an argument for 'interval'.
 upperBound' :: Num r => Interval r -> (EndPoint r, Bool)
 upperBound' (Interval _ ub) = ub
 
 instance NFData r => NFData (Interval r) where
   rnf (Interval lb ub) = rnf lb `seq` rnf ub
 
+instance Hashable r => Hashable (Interval r) where
+  hashWithSalt s (Interval lb ub) = s `hashWithSalt` lb `hashWithSalt` ub
+
 instance (Num r, Ord r) => JoinSemiLattice (Interval r) where
   join = hull
 
@@ -124,6 +135,16 @@
     (do ("empty", s) <- lex r
         return (empty, s))
 
+-- This instance preserves data abstraction at the cost of inefficiency.
+-- We omit reflection services for the sake of data abstraction.
+
+instance (Num r, Ord r, Data r) => Data (Interval r) where
+  gfoldl k z x   = z interval `k` lowerBound' x `k` upperBound' x
+  toConstr _     = error "toConstr"
+  gunfold _ _    = error "gunfold"
+  dataTypeOf _   = mkNoRepType "Data.Interval.Interval"
+  dataCast1 f    = gcast1 f
+
 -- | smart constructor for 'Interval'
 interval
   :: (Ord r, Num r)
@@ -183,7 +204,7 @@
 singleton :: (Num r, Ord r) => r -> Interval r
 singleton x = interval (Finite x, True) (Finite x, True)
 
--- | intersection (greatest lower bounds) of two intervals
+-- | intersection of two intervals
 intersection :: forall r. (Ord r, Num r) => Interval r -> Interval r -> Interval r
 intersection (Interval l1 u1) (Interval l2 u2) = interval (maxLB l1 l2) (minUB u1 u2)
   where
@@ -420,7 +441,7 @@
   = NegInf    -- ^ negative infinity (-∞)
   | Finite !r -- ^ finite value
   | PosInf    -- ^ positive infinity (+∞)
-  deriving (Ord, Eq, Show, Read, Typeable)
+  deriving (Ord, Eq, Show, Read, Typeable, Data)
 
 instance Bounded (EndPoint r) where
   minBound = NegInf
@@ -434,6 +455,11 @@
 instance NFData r => NFData (EndPoint r) where
   rnf (Finite x) = rnf x
   rnf _ = ()
+
+instance Hashable r => Hashable (EndPoint r) where
+  hashWithSalt s NegInf     = s `hashWithSalt` (0::Int)
+  hashWithSalt s (Finite x) = s `hashWithSalt` (1::Int) `hashWithSalt` x
+  hashWithSalt s PosInf     = s `hashWithSalt` (2::Int)
 
 isFinite :: EndPoint r -> Bool
 isFinite (Finite _) = True
