diff --git a/Data/Range/Data.hs b/Data/Range/Data.hs
--- a/Data/Range/Data.hs
+++ b/Data/Range/Data.hs
@@ -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.
diff --git a/Data/Range/Range.hs b/Data/Range/Range.hs
--- a/Data/Range/Range.hs
+++ b/Data/Range/Range.hs
@@ -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
diff --git a/Data/Range/RangeInternal.hs b/Data/Range/RangeInternal.hs
--- a/Data/Range/RangeInternal.hs
+++ b/Data/Range/RangeInternal.hs
@@ -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
diff --git a/Data/Range/RangeTreeInternal.hs b/Data/Range/RangeTreeInternal.hs
--- a/Data/Range/RangeTreeInternal.hs
+++ b/Data/Range/RangeTreeInternal.hs
@@ -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
diff --git a/Test/Range.hs b/Test/Range.hs
--- a/Test/Range.hs
+++ b/Test/Range.hs
@@ -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
 
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.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
