diff --git a/Data/Range.hs b/Data/Range.hs
--- a/Data/Range.hs
+++ b/Data/Range.hs
@@ -72,20 +72,21 @@
 --
 -- = Use case 2: Version ranges
 --
--- All the Data.Range library really needs to work, in the Ord type. If you have a data type that can
+-- All the 'Data.Range' library really needs to work, is the Ord type. If you have a data type that can
 -- be ordered, than we can perform range calculations on it. The Data.Version type is an excellent example
 -- of this. For example, let's say that you want to say: "I accept a version range of [1.1.0, 1.2.1] or [1.3, 1.4) or [1.4, 1.4.2)"
 -- then you can write that as:
 --
 -- >>> :m + Data.Version
--- >>> let ranges = mergeRanges [Version [1, 1, 0] [] +=+ Version [1,2,1] [], Version [1,3] [] +=* Version [1,4] [], Version [1,4] [] +=* Version [1,4,2] []]
--- >>> inRanges ranges (Version [1,0] [])
+-- >>> let v x = Version x []
+-- >>> let ranges = mergeRanges [v [1, 1, 0] +=+ v [1,2,1], v [1,3] +=* v [1,4], v [1,4] +=* v [1,4,2]]
+-- >>> inRanges ranges (v [1,0])
 -- False
--- >>> inRanges ranges (Version [1,5] [])
+-- >>> inRanges ranges (v [1,5])
 -- False
--- >>> inRanges ranges (Version [1,1,5] [])
+-- >>> inRanges ranges (v [1,1,5])
 -- True
--- >>> inRanges ranges (Version [1,3,5] [])
+-- >>> inRanges ranges (v [1,3,5])
 -- True
 --
 -- As you can see, it is almost identical to the previous example, yet you are now comparing if a version is within a version range!
@@ -138,8 +139,8 @@
 --
 -- For example:
 --
--- >>> union [SpanRange 1 10] [SpanRange 5 (15 :: Integer)]
--- [SpanRange 1 15]
+-- >>> union [1 +=+ 10] [5 +=+ (15 :: Integer)]
+-- [1 +=+ 15]
 -- (0.00 secs, 587,152 bytes)
 union :: (Ord a) => [Range a] -> [Range a] -> [Range a]
 union a b = Alg.eval $ Alg.union (Alg.const a) (Alg.const b)
@@ -150,8 +151,8 @@
 --
 -- For example:
 --
--- >>> intersection [SpanRange 1 10] [SpanRange 5 (15 :: Integer)]
--- [SpanRange 5 10]
+-- >>> intersection [1 +=* 10] [5 +=+ (15 :: Integer)]
+-- [5 +=* 10]
 -- (0.00 secs, 584,616 bytes)
 intersection :: (Ord a) => [Range a] -> [Range a] -> [Range a]
 intersection a b = Alg.eval $ Alg.intersection (Alg.const a) (Alg.const b)
@@ -162,8 +163,8 @@
 --
 -- For example:
 --
--- >>> difference [SpanRange 1 10] [SpanRange 5 (15 :: Integer)]
--- [SpanRange 1 4]
+-- >>> difference [1 +=+ 10] [5 +=+ (15 :: Integer)]
+-- [1 +=* 5]
 -- (0.00 secs, 590,424 bytes)
 difference :: (Ord a) => [Range a] -> [Range a] -> [Range a]
 difference a b = Alg.eval $ Alg.difference (Alg.const a) (Alg.const b)
@@ -173,8 +174,8 @@
 --
 -- For example:
 --
--- >>> invert [SpanRange 1 10, SpanRange 15 (20 :: Integer)]
--- [LowerBoundRange 21,UpperBoundRange 0,SpanRange 11 14]
+-- >>> invert [1 +=* 10, 15 *=+ (20 :: Integer)]
+-- [ube 1,10 +=+ 15,lbe 20]
 -- (0.00 secs, 623,456 bytes)
 invert :: (Ord a) => [Range a] -> [Range a]
 invert = Alg.eval . Alg.invert . Alg.const
diff --git a/Data/Ranges.hs b/Data/Ranges.hs
new file mode 100644
--- /dev/null
+++ b/Data/Ranges.hs
@@ -0,0 +1,107 @@
+-- | This module provides a simpler interface than the 'Data.Range' module, allowing you to work with
+-- multiple ranges at the same time.
+--
+-- One of the main advantages of this module is that it implements 'Monoid' for 'Ranges' which lets you
+-- write code like:
+-- 
+module Data.Ranges (
+  -- * Range creation
+  (+=+),
+  (+=*),
+  (*=+),
+  (*=*),
+  lbi,
+  lbe,
+  ubi,
+  ube,
+  inf,
+  -- * Comparison functions
+  inRanges,
+  aboveRanges,
+  belowRanges,
+  -- * Set operations
+  union,
+  intersection,
+  difference,
+  invert,
+  -- * Enumerable methods
+  fromRanges,
+  joinRanges,
+  -- * Data types
+  Ranges(..)
+) where
+
+import qualified Data.Range as R
+
+-- TODO Can we make this use a Range Algebra internally ?
+newtype Ranges a = Ranges { unRanges :: [R.Range a] }
+
+instance Show a => Show (Ranges a) where
+   showsPrec i (Ranges xs) = ((++) "Ranges ") . showsPrec i xs
+
+instance Ord a => Semigroup (Ranges a) where
+   (<>) (Ranges a) (Ranges b) = Ranges . R.mergeRanges $ a ++ b
+
+instance Ord a => Monoid (Ranges a) where
+   mempty = Ranges []
+   mappend (Ranges a) (Ranges b) = Ranges . R.mergeRanges $ a ++ b
+   mconcat = Ranges . R.mergeRanges . concat . fmap unRanges
+
+instance Functor Ranges where
+   fmap f (Ranges xs) = Ranges . fmap (fmap f) $ xs
+
+(+=+) :: a -> a -> Ranges a
+(+=+) a b = Ranges . pure $ (R.+=+) a b
+
+(+=*) :: a -> a -> Ranges a
+(+=*) a b = Ranges . pure $ (R.+=*) a b
+
+(*=+) :: a -> a -> Ranges a
+(*=+) a b = Ranges . pure $ (R.*=+) a b
+
+(*=*) :: a -> a -> Ranges a
+(*=*) a b = Ranges . pure $ (R.*=*) a b
+
+lbi :: a -> Ranges a
+lbi = Ranges . pure . R.lbi
+
+lbe :: a -> Ranges a
+lbe = Ranges . pure . R.lbe
+
+ubi :: a -> Ranges a
+ubi = Ranges . pure . R.ubi
+
+ube :: a -> Ranges a
+ube = Ranges . pure . R.ube
+
+inf :: Ranges a
+inf = Ranges [R.inf]
+
+inRanges :: (Ord a) => Ranges a -> a -> Bool
+inRanges (Ranges xs) = R.inRanges xs
+
+-- | Checks if the value provided is above all of the ranges provided.
+aboveRanges :: (Ord a) => Ranges a -> a -> Bool
+aboveRanges (Ranges xs) a = R.aboveRanges xs a
+
+-- | Checks if the value provided is below all of the ranges provided.
+belowRanges :: (Ord a) => Ranges a -> a -> Bool
+belowRanges (Ranges rs) a = R.belowRanges rs a
+
+union :: (Ord a) => Ranges a -> Ranges a -> Ranges a
+union (Ranges a) (Ranges b) = Ranges $ R.union a b
+
+intersection :: (Ord a) => Ranges a -> Ranges a -> Ranges a
+intersection (Ranges a) (Ranges b) = Ranges $ R.intersection a b
+
+difference :: (Ord a) => Ranges a -> Ranges a -> Ranges a
+difference (Ranges a) (Ranges b) = Ranges $ R.difference a b
+
+invert :: (Ord a) => Ranges a -> Ranges a
+invert = Ranges . R.invert . unRanges
+
+fromRanges :: (Ord a, Enum a) => Ranges a -> [a]
+fromRanges = R.fromRanges . unRanges
+
+joinRanges :: (Ord a, Enum a) => Ranges a -> Ranges a
+joinRanges = Ranges . R.joinRanges . unRanges
diff --git a/range.cabal b/range.cabal
--- a/range.cabal
+++ b/range.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.3.0.0
+version:             0.3.0.1
 
 -- A short (one-line) description of the package.
 synopsis:            An efficient and versatile range library.
@@ -56,6 +56,7 @@
 library
   -- Modules exported by the library.
   exposed-modules:    Data.Range
+                      , Data.Ranges
                       , Data.Range.Parser
                       , Data.Range.Algebra
 
