diff --git a/genvalidity-hspec.cabal b/genvalidity-hspec.cabal
--- a/genvalidity-hspec.cabal
+++ b/genvalidity-hspec.cabal
@@ -1,5 +1,5 @@
 name:                genvalidity-hspec
-version:             0.1.0.1
+version:             0.2.0.0
 synopsis:            Standard spec's for GenValidity instances
 description:         Please see README.md
 homepage:            https://github.com/NorfairKing/validity#readme
@@ -15,9 +15,9 @@
 
 library
   hs-source-dirs:      src
-  exposed-modules:     Data.GenValidity.Hspec
+  exposed-modules:     Test.Validity
   build-depends:       base                               < 5
-                     , validity   
+                     , validity                 >= 0.2 && < 0.3
                      , genvalidity
                      , QuickCheck
                      , hspec                    >= 2.2 && < 2.3
diff --git a/src/Data/GenValidity/Hspec.hs b/src/Data/GenValidity/Hspec.hs
deleted file mode 100644
--- a/src/Data/GenValidity/Hspec.hs
+++ /dev/null
@@ -1,230 +0,0 @@
-{-# LANGUAGE MultiParamTypeClasses #-}
-module Data.GenValidity.Hspec
-    ( module Data.GenValidity
-    -- * Tests for GenValidity instances
-    , proxy
-    , genspec
-    , arbitrarySpec
-    , validitySpec
-
-    -- * Standard tests involving validity
-    , producesValidsOnGen
-    , alwaysProducesValid
-    , producesValidsOnValids
-    , producesValidsOnGens2
-    , alwaysProducesValid2
-    , producesValidsOnValids2
-
-    -- * Standard tests involving functions that can fail
-
-    , CanFail(..)
-    , succeedsOnGen
-    , succeedsOnValidInput
-    , failsOnGen
-    , failsOnInvalidInput
-    , validIfSucceedsOnGen
-    , validIfSucceeds
-    ) where
-
-import           Data.GenValidity
-
-import           Test.Hspec
-import           Test.QuickCheck
-
-import           Data.Data
-
--- | A value of arbitrary type, used to specify which type to generate a spec
--- for.
-proxy :: a
-proxy = undefined
-
--- | A combination of @arbitrarySpec@ and @validitySpec@
---
--- Example usage:
---
--- > genspec (proxy :: MyData)
-genspec
-    :: (Show a, Eq a, Data a, GenValidity a, Arbitrary a)
-    => a
-    -> Spec
-genspec proxy = do
-    let name = show $ typeOf proxy
-    describe ("GenSpec for " ++ name) $ do
-        arbitrarySpec proxy
-        validitySpec proxy
-
--- | A @Spec@ that specifies that @arbitrary@ only generates data that
--- satisfy @isValid@ and that @shrink@ only produces data that satisfy
--- @isValid@.
---
--- Example usage:
---
--- > arbitrarySpec (proxy :: MyData)
-arbitrarySpec
-    :: (Typeable a, Show a, Eq a, Data a, GenValidity a, Arbitrary a)
-    => a
-    -> Spec
-arbitrarySpec proxy = do
-    let name = show $ typeOf proxy
-    describe ("Arbitrary " ++ name) $ do
-        it ("is instantiated such that 'arbitrary' only generates valid \'"
-            ++ name
-            ++ "\'s") $ do
-            forAll arbitrary $ \a ->
-                (a `asTypeOf` proxy) `shouldSatisfy` isValid
-
-        it ("is instantiated such that 'shrink' only produces valid \'"
-            ++ name
-            ++ "\'s") $ do
-            forAll arbitrary $ \a ->
-                shrink (a `asTypeOf` proxy) `shouldSatisfy` all isValid
-
--- | A @Spec@ that specifies that @genValid@ only generates valid data and that
--- @genInvalid@ only generates invalid data.
---
--- In general it is a good idea to add this spec to your test suite if you
--- write a custom implementation of @genValid@ or @genInvalid@.
---
--- Example usage:
---
--- > validitySpec (proxy :: MyData)
-validitySpec
-    :: (Typeable a, Show a, Eq a, Data a, GenValidity a, Arbitrary a)
-    => a
-    -> Spec
-validitySpec proxy = do
-    let name = show $ typeOf proxy
-    describe "genValid" $ do
-        it ("only generates valid \'" ++ name ++ "\'s") $ do
-            forAll genValid $ \a ->
-                (a `asTypeOf` proxy) `shouldSatisfy` isValid
-
-    describe "genInvalid" $ do
-        it ("only generates invalid \'" ++ name ++ "\'s") $ do
-            forAll genInvalid $ \a ->
-                (a `asTypeOf` proxy) `shouldNotSatisfy` isValid
-
-
--- | A class of types that are the result of functions that can fail
---
--- You should not use this class yourself.
-class CanFail f where
-    hasFailed :: f a -> Bool
-    resultIfSucceeded :: f a -> Maybe a
-
-instance CanFail Maybe where
-    hasFailed Nothing = True
-    hasFailed _ = False
-
-    resultIfSucceeded Nothing = Nothing
-    resultIfSucceeded (Just r) = Just r
-
-instance CanFail (Either e) where
-    hasFailed (Left _) = True
-    hasFailed _ = False
-
-    resultIfSucceeded (Left _) = Nothing
-    resultIfSucceeded (Right r) = Just r
-
--- | The function produces valid output when the input is generated as
--- specified by the given generator.
-producesValidsOnGen
-    :: (Show a, Show b, Validity b)
-    => (a -> b)
-    -> Gen a
-    -> Property
-producesValidsOnGen func gen
-    = forAll gen $ \a -> func a `shouldSatisfy` isValid
-
--- | The function produces valid output when the input is generated by
--- @genUnchecked@
-alwaysProducesValid
-    :: (Show a, Show b, GenValidity a, Validity b)
-    => (a -> b)
-    -> Property
-alwaysProducesValid = (`producesValidsOnGen` genUnchecked)
-
--- | The function produces valid output when the input is generated by
--- @genValid@
-producesValidsOnValids
-    :: (Show a, Show b, GenValidity a, Validity b)
-    => (a -> b)
-    -> Property
-producesValidsOnValids = (`producesValidsOnGen` genValid)
-
-producesValidsOnGens2
-    :: (Show a, Show b, Show c, Validity c)
-    => (a -> b -> c)
-    -> Gen a -> Gen b
-    -> Property
-producesValidsOnGens2 func gen1 gen2
-    = forAll gen1 $ \a ->
-          forAll gen2 $ \b ->
-              func a b `shouldSatisfy` isValid
-
-alwaysProducesValid2
-    :: (Show a, Show b, Show c, GenValidity a, GenValidity b, Validity c)
-    => (a -> b -> c)
-    -> Property
-alwaysProducesValid2 func
-    = producesValidsOnGens2 func genUnchecked genUnchecked
-
-producesValidsOnValids2
-    :: (Show a, Show b, Show c, GenValidity a, GenValidity b, Validity c)
-    => (a -> b -> c)
-    -> Property
-producesValidsOnValids2 func
-    = producesValidsOnGens2 func genValid genValid
-
--- | The function succeeds if the input is generated by the given generator
-succeedsOnGen
-    :: (Show a, Show b, Show (f b), CanFail f)
-    => (a -> f b)
-    -> Gen a
-    -> Property
-succeedsOnGen func gen
-    = forAll gen $ \a -> func a `shouldNotSatisfy` hasFailed
-
--- | The function succeeds if the input is generated by @genValid@
-succeedsOnValidInput
-    :: (Show a, Show b, Show (f b), GenValidity a, CanFail f)
-    => (a -> f b)
-    -> Property
-succeedsOnValidInput = (`succeedsOnGen` genValid)
-
--- | The function fails if the input is generated by the given generator
-failsOnGen
-    :: (Show a, Show b, Show (f b), CanFail f)
-    => (a -> f b)
-    -> Gen a
-    -> Property
-failsOnGen func gen
-    = forAll gen $ \a -> func a `shouldSatisfy` hasFailed
-
--- | The function fails if the input is generated by @genInvalid@
-failsOnInvalidInput
-    :: (Show a, Show b, Show (f b), GenValidity a, CanFail f)
-    => (a -> f b)
-    -> Property
-failsOnInvalidInput = (`failsOnGen` genInvalid)
-
--- | The function produces output that satisfies @isValid@ if it is given input
--- that is generated by the given generator.
-validIfSucceedsOnGen
-    :: (Show a, Show b, Show (f b), Validity b, CanFail f)
-    => (a -> f b)
-    -> Gen a
-    -> Property
-validIfSucceedsOnGen func gen
-    = forAll gen $ \a ->
-        case resultIfSucceeded (func a) of
-            Nothing  -> return () -- Can happen
-            Just res -> res `shouldSatisfy` isValid
-
--- | The function produces output that satisfies @isValid@ if it is given input
--- that is generated by @genUnchecked@.
-validIfSucceeds
-  :: (Show a, Show b, Show (f b), GenValidity a, Validity b, CanFail f)
-  => (a -> f b)
-  -> Property
-validIfSucceeds = (`validIfSucceedsOnGen` genUnchecked)
diff --git a/src/Test/Validity.hs b/src/Test/Validity.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Validity.hs
@@ -0,0 +1,393 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+module Test.Validity
+    ( module Data.GenValidity
+    , Proxy(Proxy)
+
+    -- * Tests for Arbitrary instances involving Validity
+    , arbitrarySpec
+    , arbitraryGeneratesOnlyValid
+    , shrinkProducesOnlyValids
+
+    -- * Tests for GenValidity instances
+    , genValiditySpec
+    , genValidityValidGeneratesValid
+    , genValidityInvalidGeneratesInvalid
+
+    -- * Tests for RelativeValidity instances
+    , relativeValiditySpec
+    , relativeValidityImpliesValidA
+    , relativeValidityImpliesValidB
+
+    -- * Tests for GenRelativeValidity instances
+    , genRelativeValiditySpec
+    , genRelativeValidityValidGeneratesValid
+    , genRelativeValidityInvalidGeneratesInvalid
+
+    -- * Standard tests involving validity
+    , producesValidsOnGen
+    , alwaysProducesValid
+    , producesValidsOnValids
+    , producesValidsOnGens2
+    , alwaysProducesValid2
+    , producesValidsOnValids2
+
+    -- * Standard tests involving functions that can fail
+
+    , CanFail(..)
+    , succeedsOnGen
+    , succeedsOnValidInput
+    , failsOnGen
+    , failsOnInvalidInput
+    , validIfSucceedsOnGen
+    , validIfSucceeds
+    ) where
+
+import           Data.Proxy
+import           Data.Data
+
+import           Data.GenValidity
+import           Data.GenRelativeValidity
+
+import           Test.Hspec
+import           Test.QuickCheck
+
+-- | A @Spec@ that specifies that @arbitrary@ only generates data that
+-- satisfy @isValid@ and that @shrink@ only produces data that satisfy
+-- @isValid@.
+--
+-- Example usage:
+--
+-- > arbitrarySpec (Proxy :: Proxy MyData)
+arbitrarySpec
+    :: (Typeable a, Show a, Validity a, Arbitrary a)
+    => Proxy a
+    -> Spec
+arbitrarySpec proxy = do
+    let name = nameOf proxy
+    describe ("Arbitrary " ++ name) $ do
+        it ("is instantiated such that 'arbitrary' only generates valid \'"
+            ++ name
+            ++ "\'s") $
+            arbitraryGeneratesOnlyValid proxy
+
+        it ("is instantiated such that 'shrink' only produces valid \'"
+            ++ name
+            ++ "\'s") $ do
+            forAll arbitrary $ \a ->
+                shrink (a `asProxyTypeOf` proxy) `shouldSatisfy` all isValid
+
+-- | @arbitrary@ only generates valid data
+arbitraryGeneratesOnlyValid
+    :: (Show a, Validity a, Arbitrary a)
+    => Proxy a
+    -> Property
+arbitraryGeneratesOnlyValid proxy =
+    forAll arbitrary $ \a ->
+        (a `asProxyTypeOf` proxy) `shouldSatisfy` isValid
+
+-- | @shrink@ only produces valid data
+shrinkProducesOnlyValids
+    :: (Show a, Validity a, Arbitrary a)
+    => Proxy a
+    -> Property
+shrinkProducesOnlyValids proxy =
+    forAll arbitrary $ \a ->
+        shrink (a `asProxyTypeOf` proxy) `shouldSatisfy` all isValid
+
+
+-- | A @Spec@ that specifies that @genValid@ only generates valid data and that
+-- @genInvalid@ only generates invalid data.
+--
+-- In general it is a good idea to add this spec to your test suite if you
+-- write a custom implementation of @genValid@ or @genInvalid@.
+--
+-- Example usage:
+--
+-- > genValiditySpec (Proxy :: Proxy MyData)
+genValiditySpec
+    :: (Typeable a, Show a, GenValidity a)
+    => Proxy a
+    -> Spec
+genValiditySpec proxy = do
+    let name = nameOf proxy
+    describe ("GenValidity " ++ name) $ do
+        describe ("genValid   :: Gen " ++ name) $
+            it ("only generates valid \'" ++ name ++ "\'s") $
+                genValidityValidGeneratesValid proxy
+
+        describe ("genInvalid :: Gen " ++ name) $
+            it ("only generates invalid \'" ++ name ++ "\'s") $
+                genValidityInvalidGeneratesInvalid proxy
+
+-- | @genValid@ only generates valid data
+genValidityValidGeneratesValid
+    :: (Show a, GenValidity a)
+    => Proxy a
+    -> Property
+genValidityValidGeneratesValid proxy =
+    forAll genValid $ \a ->
+        (a `asProxyTypeOf` proxy) `shouldSatisfy` isValid
+
+-- | @genValid@ only generates invalid data
+genValidityInvalidGeneratesInvalid
+    :: (Show a, GenValidity a)
+    => Proxy a
+    -> Property
+genValidityInvalidGeneratesInvalid proxy =
+    forAll genInvalid $ \a ->
+        (a `asProxyTypeOf` proxy) `shouldNotSatisfy` isValid
+
+-- | A @Spec@ that specifies that @isValidFor@ implies @isValid@
+--
+-- In general it is a good idea to add this spec to your test suite if
+-- the @a@ in @RelativeValidity a b@ also has a @Validity@ instance.
+--
+-- Example usage:
+--
+-- > relativeValiditySpec
+-- >     (Proxy :: Proxy MyDataFor)
+-- >     (Proxy :: Proxy MyOtherData)
+relativeValiditySpec
+    :: (Typeable a, Typeable b,
+        Data a, Data b,
+        Show a, Show b,
+        GenValidity a, GenValidity b, GenRelativeValidity a b)
+    => Proxy a
+    -> Proxy b
+    -> Spec
+relativeValiditySpec one two = do
+    let nameOne = nameOf one
+        nameTwo = nameOf two
+    describe ("RelativeValidity " ++ nameOne ++ " " ++ nameTwo) $ do
+        describe ("isValidFor :: "
+                  ++ nameOne
+                  ++ " -> "
+                  ++ nameTwo
+                  ++ " -> Bool") $ do
+            it ("implies isValid " ++ nameOne ++ " for any " ++ nameTwo) $
+                relativeValidityImpliesValidA one two
+            it ("implies isValid " ++ nameTwo ++ " for any " ++ nameOne) $
+                relativeValidityImpliesValidB one two
+
+-- | @isValidFor a b@ implies @isValid a@ for all @b@
+relativeValidityImpliesValidA
+    :: (Show a, Show b,
+        GenValidity a, GenValidity b, RelativeValidity a b)
+    => Proxy a
+    -> Proxy b
+    -> Property
+relativeValidityImpliesValidA one two =
+    forAll genUnchecked $ \a ->
+        forAll genUnchecked $ \b ->
+            not ((a `asProxyTypeOf` one) `isValidFor` (b `asProxyTypeOf` two))
+            || isValid a
+
+-- | @isValidFor a b@ implies @isValid b@ for all @a@
+relativeValidityImpliesValidB
+    :: (Show a, Show b,
+        GenValidity a, GenValidity b, RelativeValidity a b)
+    => Proxy a
+    -> Proxy b
+    -> Property
+relativeValidityImpliesValidB one two =
+    forAll genUnchecked $ \a ->
+        forAll genUnchecked $ \b ->
+            not ((a `asProxyTypeOf` one) `isValidFor` (b `asProxyTypeOf` two))
+              || isValid b
+
+
+-- | A @Spec@ that specifies that @genValidFor@ and @genInvalidFor@ work as
+-- intended.
+--
+-- In general it is a good idea to add this spec to your test suite if you
+-- write a custom implementation of @genValidFor@ or @genInvalidFor@.
+--
+-- Example usage:
+--
+-- > relativeGenValiditySpec (proxy :: MyDataFor) (proxy :: MyOtherData)
+genRelativeValiditySpec
+    :: (Typeable a, Typeable b,
+        Show a, Show b,
+        GenValidity a, GenValidity b,
+        RelativeValidity a b,
+        GenRelativeValidity a b)
+    => Proxy a
+    -> Proxy b
+    -> Spec
+genRelativeValiditySpec one two = do
+    let nameOne = nameOf one
+    let nameTwo = nameOf two
+    describe ("GenRelativeValidity " ++ nameOne ++ " " ++ nameTwo) $ do
+        describe ("genValidFor   :: " ++ nameTwo ++ " -> Gen " ++ nameOne) $
+            it ("only generates valid \'"
+                ++ nameOne
+                ++ "\'s for the "
+                ++ nameTwo) $
+                genRelativeValidityValidGeneratesValid one two
+
+        describe ("genInvalidFor :: " ++ nameTwo ++ " -> Gen " ++ nameOne) $
+            it ("only generates invalid \'"
+                ++ nameOne
+                ++ "\'s for the "
+                ++ nameTwo) $
+                genRelativeValidityInvalidGeneratesInvalid one two
+
+-- | @genValidFor b@ only generates values that satisfy @isValidFor b@
+genRelativeValidityValidGeneratesValid
+    :: (Show a, Show b,
+        GenValidity a, GenValidity b,
+        RelativeValidity a b,
+        GenRelativeValidity a b)
+    => Proxy a
+    -> Proxy b
+    -> Property
+genRelativeValidityValidGeneratesValid one two =
+    forAll genValid $ \b ->
+        forAll (genValidFor b) $ \a ->
+            (a `asProxyTypeOf` one)
+                `shouldSatisfy` (`isValidFor` (b `asProxyTypeOf` two))
+
+-- | @genInvalidFor b@ only generates values that do not satisfy @isValidFor b@
+genRelativeValidityInvalidGeneratesInvalid
+    :: (Show a, Show b,
+        GenValidity a, GenValidity b,
+        RelativeValidity a b,
+        GenRelativeValidity a b)
+    => Proxy a
+    -> Proxy b
+    -> Property
+genRelativeValidityInvalidGeneratesInvalid one two =
+    forAll genUnchecked $ \b ->
+        forAll (genInvalidFor b) $ \a ->
+            (a `asProxyTypeOf` one)
+                `shouldNotSatisfy` (`isValidFor` (b `asProxyTypeOf` two))
+
+-- | A class of types that are the result of functions that can fail
+--
+-- You should not use this class yourself.
+class CanFail f where
+    hasFailed :: f a -> Bool
+    resultIfSucceeded :: f a -> Maybe a
+
+instance CanFail Maybe where
+    hasFailed Nothing = True
+    hasFailed _ = False
+
+    resultIfSucceeded Nothing = Nothing
+    resultIfSucceeded (Just r) = Just r
+
+instance CanFail (Either e) where
+    hasFailed (Left _) = True
+    hasFailed _ = False
+
+    resultIfSucceeded (Left _) = Nothing
+    resultIfSucceeded (Right r) = Just r
+
+-- | The function produces valid output when the input is generated as
+-- specified by the given generator.
+producesValidsOnGen
+    :: (Show a, Show b, Validity b)
+    => (a -> b)
+    -> Gen a
+    -> Property
+producesValidsOnGen func gen
+    = forAll gen $ \a -> func a `shouldSatisfy` isValid
+
+-- | The function produces valid output when the input is generated by
+-- @genUnchecked@
+alwaysProducesValid
+    :: (Show a, Show b, GenValidity a, Validity b)
+    => (a -> b)
+    -> Property
+alwaysProducesValid = (`producesValidsOnGen` genUnchecked)
+
+-- | The function produces valid output when the input is generated by
+-- @genValid@
+producesValidsOnValids
+    :: (Show a, Show b, GenValidity a, Validity b)
+    => (a -> b)
+    -> Property
+producesValidsOnValids = (`producesValidsOnGen` genValid)
+
+producesValidsOnGens2
+    :: (Show a, Show b, Show c, Validity c)
+    => (a -> b -> c)
+    -> Gen a -> Gen b
+    -> Property
+producesValidsOnGens2 func gen1 gen2
+    = forAll gen1 $ \a ->
+          forAll gen2 $ \b ->
+              func a b `shouldSatisfy` isValid
+
+alwaysProducesValid2
+    :: (Show a, Show b, Show c, GenValidity a, GenValidity b, Validity c)
+    => (a -> b -> c)
+    -> Property
+alwaysProducesValid2 func
+    = producesValidsOnGens2 func genUnchecked genUnchecked
+
+producesValidsOnValids2
+    :: (Show a, Show b, Show c, GenValidity a, GenValidity b, Validity c)
+    => (a -> b -> c)
+    -> Property
+producesValidsOnValids2 func
+    = producesValidsOnGens2 func genValid genValid
+
+-- | The function succeeds if the input is generated by the given generator
+succeedsOnGen
+    :: (Show a, Show b, Show (f b), CanFail f)
+    => (a -> f b)
+    -> Gen a
+    -> Property
+succeedsOnGen func gen
+    = forAll gen $ \a -> func a `shouldNotSatisfy` hasFailed
+
+-- | The function succeeds if the input is generated by @genValid@
+succeedsOnValidInput
+    :: (Show a, Show b, Show (f b), GenValidity a, CanFail f)
+    => (a -> f b)
+    -> Property
+succeedsOnValidInput = (`succeedsOnGen` genValid)
+
+-- | The function fails if the input is generated by the given generator
+failsOnGen
+    :: (Show a, Show b, Show (f b), CanFail f)
+    => (a -> f b)
+    -> Gen a
+    -> Property
+failsOnGen func gen
+    = forAll gen $ \a -> func a `shouldSatisfy` hasFailed
+
+-- | The function fails if the input is generated by @genInvalid@
+failsOnInvalidInput
+    :: (Show a, Show b, Show (f b), GenValidity a, CanFail f)
+    => (a -> f b)
+    -> Property
+failsOnInvalidInput = (`failsOnGen` genInvalid)
+
+-- | The function produces output that satisfies @isValid@ if it is given input
+-- that is generated by the given generator.
+validIfSucceedsOnGen
+    :: (Show a, Show b, Show (f b), Validity b, CanFail f)
+    => (a -> f b)
+    -> Gen a
+    -> Property
+validIfSucceedsOnGen func gen
+    = forAll gen $ \a ->
+        case resultIfSucceeded (func a) of
+            Nothing  -> return () -- Can happen
+            Just res -> res `shouldSatisfy` isValid
+
+-- | The function produces output that satisfies @isValid@ if it is given input
+-- that is generated by @genUnchecked@.
+validIfSucceeds
+  :: (Show a, Show b, Show (f b), GenValidity a, Validity b, CanFail f)
+  => (a -> f b)
+  -> Property
+validIfSucceeds = (`validIfSucceedsOnGen` genUnchecked)
+
+
+nameOf :: Typeable a => Proxy a -> String
+nameOf proxy =
+    let (_, [ty]) = splitTyConApp $ typeOf proxy
+    in show ty
