diff --git a/genvalidity-property.cabal b/genvalidity-property.cabal
--- a/genvalidity-property.cabal
+++ b/genvalidity-property.cabal
@@ -1,5 +1,5 @@
 name: genvalidity-property
-version: 0.0.0.0
+version: 0.1.0.0
 cabal-version: >=1.10
 build-type: Simple
 license: MIT
@@ -8,7 +8,8 @@
 maintainer: syd.kerckhove@gmail.com
 homepage: https://github.com/NorfairKing/validity#readme
 synopsis: Standard properties for functions on `Validity` types
-description: Standard properties for functions on `Validity` types
+description:
+    Standard properties for functions on `Validity` types
 category: Testing
 author: Tom Sydney Kerckhove
 
@@ -18,7 +19,6 @@
 
 library
     exposed-modules:
-        Test.Validity.Property
         Test.Validity.Functions
         Test.Validity.Functions.CanFail
         Test.Validity.Functions.Equivalence
@@ -30,18 +30,20 @@
         Test.Validity.Operations.Associativity
         Test.Validity.Operations.Commutativity
         Test.Validity.Operations.Identity
+        Test.Validity.Property
+        Test.Validity.Property.Utils
         Test.Validity.Relations
         Test.Validity.Relations.Antireflexivity
         Test.Validity.Relations.Antisymmetry
         Test.Validity.Relations.Reflexivity
         Test.Validity.Relations.Symmetry
         Test.Validity.Relations.Transitivity
+        Test.Validity.Shrinking.Property
         Test.Validity.Types
-        Test.Validity.Property.Utils
     build-depends:
         base >=4.7 && <5,
-        validity >=0.3 && <0.4,
-        genvalidity >=0.3 && <0.4,
+        validity >=0.4 && <0.5,
+        genvalidity >=0.4 && <0.5,
         QuickCheck -any,
         hspec >=2.1 && <2.5
     default-language: Haskell2010
@@ -54,8 +56,8 @@
         base -any,
         doctest >=0.9 && <0.12,
         genvalidity-property -any,
-        directory >= 1.2 && < 1.4,
-        filepath >= 1.3 && < 1.5
+        directory >=1.2 && <1.4,
+        filepath >=1.3 && <1.5
     default-language: Haskell2010
     hs-source-dirs: test
     ghc-options: -threaded
diff --git a/src/Test/Validity/Functions/CanFail.hs b/src/Test/Validity/Functions/CanFail.hs
--- a/src/Test/Validity/Functions/CanFail.hs
+++ b/src/Test/Validity/Functions/CanFail.hs
@@ -36,87 +36,108 @@
 import Test.Validity.Types
 
 -- | 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 `shouldSatisfy` (not . hasFailed)
+succeedsOnGen ::
+       (Show a, Show b, Show (f b), CanFail f)
+    => (a -> f b)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+succeedsOnGen func gen s =
+    forAllShrink gen s $ \a -> func a `shouldSatisfy` (not . hasFailed)
 
 -- | The function succeeds if the input is generated by @genValid@
-succeedsOnValid
-    :: (Show a, Show b, Show (f b), GenValid a, CanFail f)
-    => (a -> f b) -> Property
-succeedsOnValid = (`succeedsOnGen` genValid)
+succeedsOnValid ::
+       (Show a, Show b, Show (f b), GenValid a, CanFail f)
+    => (a -> f b)
+    -> Property
+succeedsOnValid f = succeedsOnGen f genValid shrinkValid
 
 -- | The function succeeds if the input is generated by @genUnchecked@
-succeeds
-    :: (Show a, Show b, Show (f b), GenUnchecked a, CanFail f)
-    => (a -> f b) -> Property
-succeeds = (`succeedsOnGen` genUnchecked)
+succeeds ::
+       (Show a, Show b, Show (f b), GenUnchecked a, CanFail f)
+    => (a -> f b)
+    -> Property
+succeeds f = succeedsOnGen f genUnchecked shrinkUnchecked
 
 -- | The function succeeds if the input is generated by @arbitrary@
-succeedsOnArbitrary
-    :: (Show a, Show b, Show (f b), Arbitrary a, CanFail f)
-    => (a -> f b) -> Property
-succeedsOnArbitrary = (`succeedsOnGen` arbitrary)
+succeedsOnArbitrary ::
+       (Show a, Show b, Show (f b), Arbitrary a, CanFail f)
+    => (a -> f b)
+    -> Property
+succeedsOnArbitrary f = succeedsOnGen f arbitrary shrink
 
 -- | 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
+failsOnGen ::
+       (Show a, Show b, Show (f b), CanFail f)
+    => (a -> f b)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+failsOnGen func gen s =
+    forAllShrink gen s $ \a -> func a `shouldSatisfy` hasFailed
 
 -- | The function fails if the input is generated by @genInvalid@
-failsOnInvalid
-    :: (Show a, Show b, Show (f b), GenInvalid a, CanFail f)
-    => (a -> f b) -> Property
-failsOnInvalid = (`failsOnGen` genInvalid)
+failsOnInvalid ::
+       (Show a, Show b, Show (f b), GenInvalid a, CanFail f)
+    => (a -> f b)
+    -> Property
+failsOnInvalid f = failsOnGen f genInvalid shrinkInvalid
 
 -- | 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 ->
+validIfSucceedsOnGen ::
+       (Show a, Show b, Show (f b), Validity b, CanFail f)
+    => (a -> f b)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+validIfSucceedsOnGen func gen s =
+    forAllShrink gen s $ \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 @arbitrary@.
-validIfSucceedsOnValid
-    :: (Show a, Show b, Show (f b), GenValid a, Validity b, CanFail f)
-    => (a -> f b) -> Property
-validIfSucceedsOnValid = (`validIfSucceedsOnGen` genValid)
+validIfSucceedsOnValid ::
+       (Show a, Show b, Show (f b), GenValid a, Validity b, CanFail f)
+    => (a -> f b)
+    -> Property
+validIfSucceedsOnValid f = validIfSucceedsOnGen f genValid shrinkValid
 
 -- | The function produces output that satisfies @isValid@ if it is given input
 -- that is generated by @arbitrary@.
-validIfSucceedsOnArbitrary
-    :: (Show a, Show b, Show (f b), Arbitrary a, Validity b, CanFail f)
-    => (a -> f b) -> Property
-validIfSucceedsOnArbitrary = (`validIfSucceedsOnGen` arbitrary)
+validIfSucceedsOnArbitrary ::
+       (Show a, Show b, Show (f b), Arbitrary a, Validity b, CanFail f)
+    => (a -> f b)
+    -> Property
+validIfSucceedsOnArbitrary f = validIfSucceedsOnGen f arbitrary shrink
 
 -- | 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), GenUnchecked a, Validity b, CanFail f)
-    => (a -> f b) -> Property
-validIfSucceeds = (`validIfSucceedsOnGen` genUnchecked)
+validIfSucceeds ::
+       (Show a, Show b, Show (f b), GenUnchecked a, Validity b, CanFail f)
+    => (a -> f b)
+    -> Property
+validIfSucceeds f = validIfSucceedsOnGen f genUnchecked shrinkUnchecked
 
-succeedsOnGens2
-    :: (Show a, Show b, Show c, Show (f c), CanFail f)
-    => (a -> b -> f c) -> Gen (a, b) -> Property
-succeedsOnGens2 func gen =
-    forAll gen $ \(a, b) -> func a b `shouldSatisfy` (not . hasFailed)
+succeedsOnGens2 ::
+       (Show a, Show b, Show c, Show (f c), CanFail f)
+    => (a -> b -> f c)
+    -> Gen (a, b)
+    -> ((a, b) -> [(a, b)])
+    -> Property
+succeedsOnGens2 func gen s =
+    forAllShrink gen s $ \(a, b) -> func a b `shouldSatisfy` (not . hasFailed)
 
-succeedsOnValids2
-    :: (Show a, Show b, Show c, Show (f c), GenValid a, GenValid b, CanFail f)
-    => (a -> b -> f c) -> Property
-succeedsOnValids2 func = succeedsOnGens2 func genValid
+succeedsOnValids2 ::
+       (Show a, Show b, Show c, Show (f c), GenValid a, GenValid b, CanFail f)
+    => (a -> b -> f c)
+    -> Property
+succeedsOnValids2 func = succeedsOnGens2 func genValid shrinkValid
 
-succeeds2
-    :: ( Show a
+succeeds2 ::
+       ( Show a
        , Show b
        , Show c
        , Show (f c)
@@ -124,22 +145,30 @@
        , GenUnchecked b
        , CanFail f
        )
-    => (a -> b -> f c) -> Property
-succeeds2 func = succeedsOnGens2 func genUnchecked
+    => (a -> b -> f c)
+    -> Property
+succeeds2 func = succeedsOnGens2 func genUnchecked shrinkUnchecked
 
-succeedsOnArbitrary2
-    :: (Show a, Show b, Show c, Show (f c), Arbitrary a, Arbitrary b, CanFail f)
-    => (a -> b -> f c) -> Property
-succeedsOnArbitrary2 func = succeedsOnGens2 func arbitrary
+succeedsOnArbitrary2 ::
+       (Show a, Show b, Show c, Show (f c), Arbitrary a, Arbitrary b, CanFail f)
+    => (a -> b -> f c)
+    -> Property
+succeedsOnArbitrary2 func = succeedsOnGens2 func arbitrary shrink
 
-failsOnGens2
-    :: (Show a, Show b, Show c, Show (f c), CanFail f)
-    => (a -> b -> f c) -> Gen a -> Gen b -> Property
-failsOnGens2 func genA genB =
-    forAll genA $ \a -> forAll genB $ \b -> func a b `shouldSatisfy` hasFailed
+failsOnGens2 ::
+       (Show a, Show b, Show c, Show (f c), CanFail f)
+    => (a -> b -> f c)
+    -> Gen a
+    -> (a -> [a])
+    -> Gen b
+    -> (b -> [b])
+    -> Property
+failsOnGens2 func genA sA genB sB =
+    forAllShrink genA sA $ \a ->
+        forAllShrink genB sB $ \b -> func a b `shouldSatisfy` hasFailed
 
-failsOnInvalid2
-    :: ( Show a
+failsOnInvalid2 ::
+       ( Show a
        , Show b
        , Show c
        , Show (f c)
@@ -147,22 +176,26 @@
        , GenInvalid b
        , CanFail f
        )
-    => (a -> b -> f c) -> Property
+    => (a -> b -> f c)
+    -> Property
 failsOnInvalid2 func =
-    failsOnGens2 func genInvalid genUnchecked .&&.
-    failsOnGens2 func genUnchecked genInvalid
+    failsOnGens2 func genInvalid shrinkInvalid genUnchecked shrinkUnchecked .&&.
+    failsOnGens2 func genUnchecked shrinkUnchecked genInvalid shrinkInvalid
 
-validIfSucceedsOnGens2
-    :: (Show a, Show b, Show c, Show (f c), Validity c, CanFail f)
-    => (a -> b -> f c) -> Gen (a, b) -> Property
-validIfSucceedsOnGens2 func gen =
-    forAll gen $ \(a, b) ->
+validIfSucceedsOnGens2 ::
+       (Show a, Show b, Show c, Show (f c), Validity c, CanFail f)
+    => (a -> b -> f c)
+    -> Gen (a, b)
+    -> ((a, b) -> [(a, b)])
+    -> Property
+validIfSucceedsOnGens2 func gen s =
+    forAllShrink gen s $ \(a, b) ->
         case resultIfSucceeded (func a b) of
             Nothing -> return () -- Can happen
             Just res -> res `shouldSatisfy` isValid
 
-validIfSucceedsOnValids2
-    :: ( Show a
+validIfSucceedsOnValids2 ::
+       ( Show a
        , Show b
        , Show c
        , Show (f c)
@@ -171,11 +204,12 @@
        , Validity c
        , CanFail f
        )
-    => (a -> b -> f c) -> Property
-validIfSucceedsOnValids2 func = validIfSucceedsOnGens2 func genValid
+    => (a -> b -> f c)
+    -> Property
+validIfSucceedsOnValids2 func = validIfSucceedsOnGens2 func genValid shrinkValid
 
-validIfSucceeds2
-    :: ( Show a
+validIfSucceeds2 ::
+       ( Show a
        , Show b
        , Show c
        , Show (f c)
@@ -184,11 +218,12 @@
        , Validity c
        , CanFail f
        )
-    => (a -> b -> f c) -> Property
-validIfSucceeds2 func = validIfSucceedsOnGens2 func genUnchecked
+    => (a -> b -> f c)
+    -> Property
+validIfSucceeds2 func = validIfSucceedsOnGens2 func genUnchecked shrinkUnchecked
 
-validIfSucceedsOnArbitrary2
-    :: ( Show a
+validIfSucceedsOnArbitrary2 ::
+       ( Show a
        , Show b
        , Show c
        , Show (f c)
@@ -197,20 +232,24 @@
        , Validity c
        , CanFail f
        )
-    => (a -> b -> f c) -> Property
-validIfSucceedsOnArbitrary2 func = validIfSucceedsOnGens2 func arbitrary
+    => (a -> b -> f c)
+    -> Property
+validIfSucceedsOnArbitrary2 func = validIfSucceedsOnGens2 func arbitrary shrink
 
-validIfSucceedsOnGens3
-    :: (Show a, Show b, Show c, Show d, Show (f d), Validity d, CanFail f)
-    => (a -> b -> c -> f d) -> Gen (a, b, c) -> Property
-validIfSucceedsOnGens3 func gen =
-    forAll gen $ \(a, b, c) ->
+validIfSucceedsOnGens3 ::
+       (Show a, Show b, Show c, Show d, Show (f d), Validity d, CanFail f)
+    => (a -> b -> c -> f d)
+    -> Gen (a, b, c)
+    -> ((a, b, c) -> [(a, b, c)])
+    -> Property
+validIfSucceedsOnGens3 func gen s =
+    forAllShrink gen s $ \(a, b, c) ->
         case resultIfSucceeded (func a b c) of
             Nothing -> return () -- Can happen
             Just res -> res `shouldSatisfy` isValid
 
-validIfSucceedsOnValids3
-    :: ( Show a
+validIfSucceedsOnValids3 ::
+       ( Show a
        , Show b
        , Show c
        , Show d
@@ -221,11 +260,12 @@
        , Validity d
        , CanFail f
        )
-    => (a -> b -> c -> f d) -> Property
-validIfSucceedsOnValids3 func = validIfSucceedsOnGens3 func genValid
+    => (a -> b -> c -> f d)
+    -> Property
+validIfSucceedsOnValids3 func = validIfSucceedsOnGens3 func genValid shrinkValid
 
-validIfSucceeds3
-    :: ( Show a
+validIfSucceeds3 ::
+       ( Show a
        , Show b
        , Show c
        , Show d
@@ -236,11 +276,12 @@
        , Validity d
        , CanFail f
        )
-    => (a -> b -> c -> f d) -> Property
-validIfSucceeds3 func = validIfSucceedsOnGens3 func genUnchecked
+    => (a -> b -> c -> f d)
+    -> Property
+validIfSucceeds3 func = validIfSucceedsOnGens3 func genUnchecked shrinkUnchecked
 
-validIfSucceedsOnArbitrary3
-    :: ( Show a
+validIfSucceedsOnArbitrary3 ::
+       ( Show a
        , Show b
        , Show c
        , Show d
@@ -251,5 +292,6 @@
        , Validity d
        , CanFail f
        )
-    => (a -> b -> c -> f d) -> Property
-validIfSucceedsOnArbitrary3 func = validIfSucceedsOnGens3 func arbitrary
+    => (a -> b -> c -> f d)
+    -> Property
+validIfSucceedsOnArbitrary3 func = validIfSucceedsOnGens3 func arbitrary shrink
diff --git a/src/Test/Validity/Functions/Equivalence.hs b/src/Test/Validity/Functions/Equivalence.hs
--- a/src/Test/Validity/Functions/Equivalence.hs
+++ b/src/Test/Validity/Functions/Equivalence.hs
@@ -47,90 +47,124 @@
 
 import Test.Validity.Types
 
-equivalentOnGen
-    :: (Show a, Eq a, Show b, Eq b)
-    => (a -> b) -> (a -> b) -> Gen a -> Property
-equivalentOnGen f g gen = forAll gen $ \a -> f a `shouldBe` g a
+equivalentOnGen ::
+       (Show a, Eq a, Show b, Eq b)
+    => (a -> b)
+    -> (a -> b)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+equivalentOnGen f g gen s = forAllShrink gen s $ \a -> f a `shouldBe` g a
 
-equivalentOnValid
-    :: (Show a, Eq a, GenValid a, Show b, Eq b)
-    => (a -> b) -> (a -> b) -> Property
-equivalentOnValid f g = equivalentOnGen f g genValid
+equivalentOnValid ::
+       (Show a, Eq a, GenValid a, Show b, Eq b)
+    => (a -> b)
+    -> (a -> b)
+    -> Property
+equivalentOnValid f g = equivalentOnGen f g genValid shrinkValid
 
-equivalent
-    :: (Show a, Eq a, GenUnchecked a, Show b, Eq b)
-    => (a -> b) -> (a -> b) -> Property
-equivalent f g = equivalentOnGen f g genUnchecked
+equivalent ::
+       (Show a, Eq a, GenUnchecked a, Show b, Eq b)
+    => (a -> b)
+    -> (a -> b)
+    -> Property
+equivalent f g = equivalentOnGen f g genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> equivalentOnArbitrary ((* 2) . (+ 1)) ((+ 2) . (* 2) :: Int -> Int)
-equivalentOnArbitrary
-    :: (Show a, Eq a, Arbitrary a, Show b, Eq b)
-    => (a -> b) -> (a -> b) -> Property
-equivalentOnArbitrary f g = equivalentOnGen f g arbitrary
+equivalentOnArbitrary ::
+       (Show a, Eq a, Arbitrary a, Show b, Eq b)
+    => (a -> b)
+    -> (a -> b)
+    -> Property
+equivalentOnArbitrary f g = equivalentOnGen f g arbitrary shrink
 
-equivalentOnGens2
-    :: (Show a, Show b, Show c, Eq c)
-    => (a -> b -> c) -> (a -> b -> c) -> Gen (a, b) -> Property
-equivalentOnGens2 f g gen = forAll gen $ \(a, b) -> f a b `shouldBe` g a b
+equivalentOnGens2 ::
+       (Show a, Show b, Show c, Eq c)
+    => (a -> b -> c)
+    -> (a -> b -> c)
+    -> Gen (a, b)
+    -> ((a, b) -> [(a, b)])
+    -> Property
+equivalentOnGens2 f g gen s = forAllShrink gen s $ \(a, b) -> f a b `shouldBe` g a b
 
-equivalentOnValids2
-    :: (Show a, GenValid a, Show b, GenValid b, Show c, Eq c)
-    => (a -> b -> c) -> (a -> b -> c) -> Property
-equivalentOnValids2 f g = equivalentOnGens2 f g genValid
+equivalentOnValids2 ::
+       (Show a, GenValid a, Show b, GenValid b, Show c, Eq c)
+    => (a -> b -> c)
+    -> (a -> b -> c)
+    -> Property
+equivalentOnValids2 f g = equivalentOnGens2 f g genValid shrinkValid
 
-equivalent2
-    :: (Show a, GenUnchecked a, Show b, GenUnchecked b, Show c, Eq c)
-    => (a -> b -> c) -> (a -> b -> c) -> Property
-equivalent2 f g = equivalentOnGens2 f g genUnchecked
+equivalent2 ::
+       (Show a, GenUnchecked a, Show b, GenUnchecked b, Show c, Eq c)
+    => (a -> b -> c)
+    -> (a -> b -> c)
+    -> Property
+equivalent2 f g = equivalentOnGens2 f g genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> equivalentOnArbitrary2 (+) ((+) :: Int -> Int -> Int)
-equivalentOnArbitrary2
-    :: (Show a, Arbitrary a, Show b, Arbitrary b, Show c, Eq c)
-    => (a -> b -> c) -> (a -> b -> c) -> Property
-equivalentOnArbitrary2 f g = equivalentOnGens2 f g arbitrary
+equivalentOnArbitrary2 ::
+       (Show a, Arbitrary a, Show b, Arbitrary b, Show c, Eq c)
+    => (a -> b -> c)
+    -> (a -> b -> c)
+    -> Property
+equivalentOnArbitrary2 f g = equivalentOnGens2 f g arbitrary shrink
 
-equivalentWhenFirstSucceedsOnGen
-    :: (Show a, Eq a, Show b, Eq b, CanFail f)
-    => (a -> f b) -> (a -> b) -> Gen a -> Property
-equivalentWhenFirstSucceedsOnGen f g gen =
-    forAll gen $ \a ->
+equivalentWhenFirstSucceedsOnGen ::
+       (Show a, Eq a, Show b, Eq b, CanFail f)
+    => (a -> f b)
+    -> (a -> b)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+equivalentWhenFirstSucceedsOnGen f g gen s =
+    forAllShrink gen s $ \a ->
         case resultIfSucceeded (f a) of
             Nothing -> return () -- fine
             Just r -> r `shouldBe` g a
 
-equivalentWhenFirstSucceedsOnValid
-    :: (Show a, Eq a, GenValid a, Show b, Eq b, CanFail f)
-    => (a -> f b) -> (a -> b) -> Property
+equivalentWhenFirstSucceedsOnValid ::
+       (Show a, Eq a, GenValid a, Show b, Eq b, CanFail f)
+    => (a -> f b)
+    -> (a -> b)
+    -> Property
 equivalentWhenFirstSucceedsOnValid f g =
-    equivalentWhenFirstSucceedsOnGen f g genValid
+    equivalentWhenFirstSucceedsOnGen f g genValid shrinkValid
 
-equivalentWhenFirstSucceedsOnArbitrary
-    :: (Show a, Eq a, Arbitrary a, Show b, Eq b, CanFail f)
-    => (a -> f b) -> (a -> b) -> Property
+equivalentWhenFirstSucceedsOnArbitrary ::
+       (Show a, Eq a, Arbitrary a, Show b, Eq b, CanFail f)
+    => (a -> f b)
+    -> (a -> b)
+    -> Property
 equivalentWhenFirstSucceedsOnArbitrary f g =
-    equivalentWhenFirstSucceedsOnGen f g arbitrary
+    equivalentWhenFirstSucceedsOnGen f g arbitrary shrink
 
-equivalentWhenFirstSucceeds
-    :: (Show a, Eq a, GenUnchecked a, Show b, Eq b, CanFail f)
-    => (a -> f b) -> (a -> b) -> Property
+equivalentWhenFirstSucceeds ::
+       (Show a, Eq a, GenUnchecked a, Show b, Eq b, CanFail f)
+    => (a -> f b)
+    -> (a -> b)
+    -> Property
 equivalentWhenFirstSucceeds f g =
-    equivalentWhenFirstSucceedsOnGen f g genUnchecked
+    equivalentWhenFirstSucceedsOnGen f g genUnchecked shrinkUnchecked
 
-equivalentWhenFirstSucceedsOnGens2
-    :: (Show a, Eq a, Show b, Eq b, Show c, Eq c, CanFail f)
-    => (a -> b -> f c) -> (a -> b -> c) -> Gen (a, b) -> Property
-equivalentWhenFirstSucceedsOnGens2 f g gen =
-    forAll gen $ \(a, b) ->
+equivalentWhenFirstSucceedsOnGens2 ::
+       (Show a, Eq a, Show b, Eq b, Show c, Eq c, CanFail f)
+    => (a -> b -> f c)
+    -> (a -> b -> c)
+    -> Gen (a, b)
+    -> ((a, b) -> [(a, b)])
+    -> Property
+equivalentWhenFirstSucceedsOnGens2 f g gen s =
+    forAllShrink gen s $ \(a, b) ->
         case resultIfSucceeded (f a b) of
             Nothing -> return () -- fine
             Just rs -> rs `shouldBe` g a b
 
-equivalentWhenFirstSucceedsOnValids2
-    :: ( Show a
+equivalentWhenFirstSucceedsOnValids2 ::
+       ( Show a
        , Eq a
        , GenValid a
        , Show b
@@ -140,12 +174,14 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> f c) -> (a -> b -> c) -> Property
+    => (a -> b -> f c)
+    -> (a -> b -> c)
+    -> Property
 equivalentWhenFirstSucceedsOnValids2 f g =
-    equivalentWhenFirstSucceedsOnGens2 f g genValid
+    equivalentWhenFirstSucceedsOnGens2 f g genValid shrinkValid
 
-equivalentWhenFirstSucceedsOnArbitrary2
-    :: ( Show a
+equivalentWhenFirstSucceedsOnArbitrary2 ::
+       ( Show a
        , Eq a
        , Arbitrary a
        , Show b
@@ -155,12 +191,14 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> f c) -> (a -> b -> c) -> Property
+    => (a -> b -> f c)
+    -> (a -> b -> c)
+    -> Property
 equivalentWhenFirstSucceedsOnArbitrary2 f g =
-    equivalentWhenFirstSucceedsOnGens2 f g arbitrary
+    equivalentWhenFirstSucceedsOnGens2 f g arbitrary shrink
 
-equivalentWhenFirstSucceeds2
-    :: ( Show a
+equivalentWhenFirstSucceeds2 ::
+       ( Show a
        , Eq a
        , GenUnchecked a
        , Show b
@@ -170,48 +208,64 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> f c) -> (a -> b -> c) -> Property
+    => (a -> b -> f c)
+    -> (a -> b -> c)
+    -> Property
 equivalentWhenFirstSucceeds2 f g =
-    equivalentWhenFirstSucceedsOnGens2 f g genUnchecked
+    equivalentWhenFirstSucceedsOnGens2 f g genUnchecked shrinkUnchecked
 
-equivalentWhenSecondSucceedsOnGen
-    :: (Show a, Eq a, Show b, Eq b, CanFail f)
-    => (a -> b) -> (a -> f b) -> Gen a -> Property
-equivalentWhenSecondSucceedsOnGen f g gen =
-    forAll gen $ \a ->
+equivalentWhenSecondSucceedsOnGen ::
+       (Show a, Eq a, Show b, Eq b, CanFail f)
+    => (a -> b)
+    -> (a -> f b)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+equivalentWhenSecondSucceedsOnGen f g gen s =
+    forAllShrink gen s $ \a ->
         case resultIfSucceeded (g a) of
             Nothing -> return () -- fine
             Just r -> r `shouldBe` f a
 
-equivalentWhenSecondSucceedsOnValid
-    :: (Show a, Eq a, GenValid a, Show b, Eq b, CanFail f)
-    => (a -> b) -> (a -> f b) -> Property
+equivalentWhenSecondSucceedsOnValid ::
+       (Show a, Eq a, GenValid a, Show b, Eq b, CanFail f)
+    => (a -> b)
+    -> (a -> f b)
+    -> Property
 equivalentWhenSecondSucceedsOnValid f g =
-    equivalentWhenSecondSucceedsOnGen f g genValid
+    equivalentWhenSecondSucceedsOnGen f g genValid shrinkValid
 
-equivalentWhenSecondSucceedsOnArbitrary
-    :: (Show a, Eq a, Arbitrary a, Show b, Eq b, CanFail f)
-    => (a -> b) -> (a -> f b) -> Property
+equivalentWhenSecondSucceedsOnArbitrary ::
+       (Show a, Eq a, Arbitrary a, Show b, Eq b, CanFail f)
+    => (a -> b)
+    -> (a -> f b)
+    -> Property
 equivalentWhenSecondSucceedsOnArbitrary f g =
-    equivalentWhenSecondSucceedsOnGen f g arbitrary
+    equivalentWhenSecondSucceedsOnGen f g arbitrary shrink
 
-equivalentWhenSecondSucceeds
-    :: (Show a, Eq a, GenUnchecked a, Show b, Eq b, CanFail f)
-    => (a -> b) -> (a -> f b) -> Property
+equivalentWhenSecondSucceeds ::
+       (Show a, Eq a, GenUnchecked a, Show b, Eq b, CanFail f)
+    => (a -> b)
+    -> (a -> f b)
+    -> Property
 equivalentWhenSecondSucceeds f g =
-    equivalentWhenSecondSucceedsOnGen f g genUnchecked
+    equivalentWhenSecondSucceedsOnGen f g genUnchecked shrinkUnchecked
 
-equivalentWhenSecondSucceedsOnGens2
-    :: (Show a, Eq a, Show b, Eq b, Show c, Eq c, CanFail f)
-    => (a -> b -> c) -> (a -> b -> f c) -> Gen (a, b) -> Property
-equivalentWhenSecondSucceedsOnGens2 f g gen =
-    forAll gen $ \(a, b) ->
+equivalentWhenSecondSucceedsOnGens2 ::
+       (Show a, Eq a, Show b, Eq b, Show c, Eq c, CanFail f)
+    => (a -> b -> c)
+    -> (a -> b -> f c)
+    -> Gen (a, b)
+    -> ((a, b) -> [(a, b)])
+    -> Property
+equivalentWhenSecondSucceedsOnGens2 f g gen s =
+    forAllShrink gen s $ \(a, b) ->
         case resultIfSucceeded (g a b) of
             Nothing -> return () -- fine
             Just rs -> rs `shouldBe` f a b
 
-equivalentWhenSecondSucceedsOnValids2
-    :: ( Show a
+equivalentWhenSecondSucceedsOnValids2 ::
+       ( Show a
        , Eq a
        , GenValid a
        , Show b
@@ -221,12 +275,14 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> c) -> (a -> b -> f c) -> Property
+    => (a -> b -> c)
+    -> (a -> b -> f c)
+    -> Property
 equivalentWhenSecondSucceedsOnValids2 f g =
-    equivalentWhenSecondSucceedsOnGens2 f g genValid
+    equivalentWhenSecondSucceedsOnGens2 f g genValid shrinkValid
 
-equivalentWhenSecondSucceedsOnArbitrary2
-    :: ( Show a
+equivalentWhenSecondSucceedsOnArbitrary2 ::
+       ( Show a
        , Eq a
        , Arbitrary a
        , Show b
@@ -236,12 +292,14 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> c) -> (a -> b -> f c) -> Property
+    => (a -> b -> c)
+    -> (a -> b -> f c)
+    -> Property
 equivalentWhenSecondSucceedsOnArbitrary2 f g =
-    equivalentWhenSecondSucceedsOnGens2 f g arbitrary
+    equivalentWhenSecondSucceedsOnGens2 f g arbitrary shrink
 
-equivalentWhenSecondSucceeds2
-    :: ( Show a
+equivalentWhenSecondSucceeds2 ::
+       ( Show a
        , Eq a
        , GenUnchecked a
        , Show b
@@ -251,49 +309,68 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> c) -> (a -> b -> f c) -> Property
+    => (a -> b -> c)
+    -> (a -> b -> f c)
+    -> Property
 equivalentWhenSecondSucceeds2 f g =
-    equivalentWhenSecondSucceedsOnGens2 f g genUnchecked
+    equivalentWhenSecondSucceedsOnGens2 f g genUnchecked shrinkUnchecked
 
-equivalentWhenSucceedOnGen
-    :: (Show a, Eq a, Show b, Eq b, CanFail f)
-    => (a -> f b) -> (a -> f b) -> Gen a -> Property
-equivalentWhenSucceedOnGen f g gen =
-    forAll gen $ \a ->
+equivalentWhenSucceedOnGen ::
+       (Show a, Eq a, Show b, Eq b, CanFail f)
+    => (a -> f b)
+    -> (a -> f b)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+equivalentWhenSucceedOnGen f g gen s =
+    forAllShrink gen s $ \a ->
         case do fa <- resultIfSucceeded $ f a
                 ga <- resultIfSucceeded $ g a
                 return (fa, ga) of
             Nothing -> return () -- fine
             Just (fa, ga) -> fa `shouldBe` ga
 
-equivalentWhenSucceedOnValid
-    :: (Show a, Eq a, GenValid a, Show b, Eq b, CanFail f)
-    => (a -> f b) -> (a -> f b) -> Property
-equivalentWhenSucceedOnValid f g = equivalentWhenSucceedOnGen f g genValid
+equivalentWhenSucceedOnValid ::
+       (Show a, Eq a, GenValid a, Show b, Eq b, CanFail f)
+    => (a -> f b)
+    -> (a -> f b)
+    -> Property
+equivalentWhenSucceedOnValid f g =
+    equivalentWhenSucceedOnGen f g genValid shrinkValid
 
-equivalentWhenSucceed
-    :: (Show a, Eq a, GenUnchecked a, Show b, Eq b, CanFail f)
-    => (a -> f b) -> (a -> f b) -> Property
-equivalentWhenSucceed f g = equivalentWhenSucceedOnGen f g genUnchecked
+equivalentWhenSucceed ::
+       (Show a, Eq a, GenUnchecked a, Show b, Eq b, CanFail f)
+    => (a -> f b)
+    -> (a -> f b)
+    -> Property
+equivalentWhenSucceed f g =
+    equivalentWhenSucceedOnGen f g genUnchecked shrinkUnchecked
 
-equivalentWhenSucceedOnArbitrary
-    :: (Show a, Eq a, Arbitrary a, Show b, Eq b, CanFail f)
-    => (a -> f b) -> (a -> f b) -> Property
-equivalentWhenSucceedOnArbitrary f g = equivalentWhenSucceedOnGen f g arbitrary
+equivalentWhenSucceedOnArbitrary ::
+       (Show a, Eq a, Arbitrary a, Show b, Eq b, CanFail f)
+    => (a -> f b)
+    -> (a -> f b)
+    -> Property
+equivalentWhenSucceedOnArbitrary f g =
+    equivalentWhenSucceedOnGen f g arbitrary shrink
 
-equivalentWhenSucceedOnGens2
-    :: (Show a, Eq a, Show b, Eq b, Show c, Eq c, CanFail f)
-    => (a -> b -> f c) -> (a -> b -> f c) -> Gen (a, b) -> Property
-equivalentWhenSucceedOnGens2 f g gen =
-    forAll gen $ \(a, b) ->
+equivalentWhenSucceedOnGens2 ::
+       (Show a, Eq a, Show b, Eq b, Show c, Eq c, CanFail f)
+    => (a -> b -> f c)
+    -> (a -> b -> f c)
+    -> Gen (a, b)
+    -> ((a, b) -> [(a, b)])
+    -> Property
+equivalentWhenSucceedOnGens2 f g gen s =
+    forAllShrink gen s $ \(a, b) ->
         case do fab <- resultIfSucceeded $ f a b
                 gab <- resultIfSucceeded $ g a b
                 return (fab, gab) of
             Nothing -> return () -- fine
             Just (fab, gab) -> fab `shouldBe` gab
 
-equivalentWhenSucceedOnValids2
-    :: ( Show a
+equivalentWhenSucceedOnValids2 ::
+       ( Show a
        , Eq a
        , GenValid a
        , Show b
@@ -303,11 +380,14 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> f c) -> (a -> b -> f c) -> Property
-equivalentWhenSucceedOnValids2 f g = equivalentWhenSucceedOnGens2 f g genValid
+    => (a -> b -> f c)
+    -> (a -> b -> f c)
+    -> Property
+equivalentWhenSucceedOnValids2 f g =
+    equivalentWhenSucceedOnGens2 f g genValid shrinkValid
 
-equivalentWhenSucceedOnArbitrary2
-    :: ( Show a
+equivalentWhenSucceedOnArbitrary2 ::
+       ( Show a
        , Eq a
        , Arbitrary a
        , Show b
@@ -317,12 +397,14 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> f c) -> (a -> b -> f c) -> Property
+    => (a -> b -> f c)
+    -> (a -> b -> f c)
+    -> Property
 equivalentWhenSucceedOnArbitrary2 f g =
-    equivalentWhenSucceedOnGens2 f g arbitrary
+    equivalentWhenSucceedOnGens2 f g arbitrary shrink
 
-equivalentWhenSucceed2
-    :: ( Show a
+equivalentWhenSucceed2 ::
+       ( Show a
        , Eq a
        , GenUnchecked a
        , Show b
@@ -332,17 +414,24 @@
        , Eq c
        , CanFail f
        )
-    => (a -> b -> f c) -> (a -> b -> f c) -> Property
-equivalentWhenSucceed2 f g = equivalentWhenSucceedOnGens2 f g genUnchecked
+    => (a -> b -> f c)
+    -> (a -> b -> f c)
+    -> Property
+equivalentWhenSucceed2 f g =
+    equivalentWhenSucceedOnGens2 f g genUnchecked shrinkUnchecked
 
-equivalentOnGens3
-    :: (Show a, Show b, Show c, Show d, Eq d)
-    => (a -> b -> c -> d) -> (a -> b -> c -> d) -> Gen (a, b, c) -> Property
-equivalentOnGens3 f g gen =
-    forAll gen $ \(a, b, c) -> f a b c `shouldBe` g a b c
+equivalentOnGens3 ::
+       (Show a, Show b, Show c, Show d, Eq d)
+    => (a -> b -> c -> d)
+    -> (a -> b -> c -> d)
+    -> Gen (a, b, c)
+    -> ((a, b, c) -> [(a, b, c)])
+    -> Property
+equivalentOnGens3 f g gen s =
+    forAllShrink gen s $ \(a, b, c) -> f a b c `shouldBe` g a b c
 
-equivalentOnValids3
-    :: ( Show a
+equivalentOnValids3 ::
+       ( Show a
        , GenValid a
        , Show b
        , GenValid b
@@ -351,11 +440,13 @@
        , Show d
        , Eq d
        )
-    => (a -> b -> c -> d) -> (a -> b -> c -> d) -> Property
-equivalentOnValids3 f g = equivalentOnGens3 f g genValid
+    => (a -> b -> c -> d)
+    -> (a -> b -> c -> d)
+    -> Property
+equivalentOnValids3 f g = equivalentOnGens3 f g genValid shrinkValid
 
-equivalent3
-    :: ( Show a
+equivalent3 ::
+       ( Show a
        , GenUnchecked a
        , Show b
        , GenUnchecked b
@@ -364,11 +455,13 @@
        , Show d
        , Eq d
        )
-    => (a -> b -> c -> d) -> (a -> b -> c -> d) -> Property
-equivalent3 f g = equivalentOnGens3 f g genUnchecked
+    => (a -> b -> c -> d)
+    -> (a -> b -> c -> d)
+    -> Property
+equivalent3 f g = equivalentOnGens3 f g genUnchecked shrinkUnchecked
 
-equivalentOnArbitrary3
-    :: ( Show a
+equivalentOnArbitrary3 ::
+       ( Show a
        , Arbitrary a
        , Show b
        , Arbitrary b
@@ -377,5 +470,7 @@
        , Show d
        , Eq d
        )
-    => (a -> b -> c -> d) -> (a -> b -> c -> d) -> Property
-equivalentOnArbitrary3 f g = equivalentOnGens3 f g arbitrary
+    => (a -> b -> c -> d)
+    -> (a -> b -> c -> d)
+    -> Property
+equivalentOnArbitrary3 f g = equivalentOnGens3 f g arbitrary shrink
diff --git a/src/Test/Validity/Functions/Idempotence.hs b/src/Test/Validity/Functions/Idempotence.hs
--- a/src/Test/Validity/Functions/Idempotence.hs
+++ b/src/Test/Validity/Functions/Idempotence.hs
@@ -16,18 +16,18 @@
 
 idempotentOnGen
     :: (Show a, Eq a)
-    => (a -> a) -> Gen a -> Property
-idempotentOnGen f gen = forAll gen $ \a -> f (f a) `shouldBe` f a
+    => (a -> a) -> Gen a -> (a -> [a]) -> Property
+idempotentOnGen f gen s = forAllShrink gen s $ \a -> f (f a) `shouldBe` f a
 
 idempotentOnValid
     :: (Show a, Eq a, GenValid a)
     => (a -> a) -> Property
-idempotentOnValid func = idempotentOnGen func genValid
+idempotentOnValid func = idempotentOnGen func genValid shrinkValid
 
 idempotent
     :: (Show a, Eq a, GenUnchecked a)
     => (a -> a) -> Property
-idempotent func = idempotentOnGen func genUnchecked
+idempotent func = idempotentOnGen func genUnchecked shrinkUnchecked
 
 -- |
 --
@@ -41,4 +41,4 @@
 idempotentOnArbitrary
     :: (Show a, Eq a, Arbitrary a)
     => (a -> a) -> Property
-idempotentOnArbitrary func = idempotentOnGen func arbitrary
+idempotentOnArbitrary func = idempotentOnGen func arbitrary shrink
diff --git a/src/Test/Validity/Functions/Inverse.hs b/src/Test/Validity/Functions/Inverse.hs
--- a/src/Test/Validity/Functions/Inverse.hs
+++ b/src/Test/Validity/Functions/Inverse.hs
@@ -28,106 +28,134 @@
 
 import Test.Validity.Types
 
-inverseFunctionsOnGen
-    :: (Show a, Eq a)
-    => (a -> b) -> (b -> a) -> Gen a -> Property
-inverseFunctionsOnGen f g gen = forAll gen $ \a -> g (f a) `shouldBe` a
+inverseFunctionsOnGen ::
+       (Show a, Eq a) => (a -> b) -> (b -> a) -> Gen a -> (a -> [a]) -> Property
+inverseFunctionsOnGen f g gen s =
+    forAllShrink gen s $ \a -> g (f a) `shouldBe` a
 
-inverseFunctionsOnValid
-    :: (Show a, Eq a, GenValid a)
-    => (a -> b) -> (b -> a) -> Property
-inverseFunctionsOnValid f g = inverseFunctionsOnGen f g genValid
+inverseFunctionsOnValid ::
+       (Show a, Eq a, GenValid a) => (a -> b) -> (b -> a) -> Property
+inverseFunctionsOnValid f g = inverseFunctionsOnGen f g genValid shrinkValid
 
-inverseFunctions
-    :: (Show a, Eq a, GenUnchecked a)
-    => (a -> b) -> (b -> a) -> Property
-inverseFunctions f g = inverseFunctionsOnGen f g genUnchecked
+inverseFunctions ::
+       (Show a, Eq a, GenUnchecked a) => (a -> b) -> (b -> a) -> Property
+inverseFunctions f g = inverseFunctionsOnGen f g genUnchecked shrinkUnchecked
 
 -- |
 -- 'id' is its own inverse function for every type:
 -- prop> inverseFunctionsOnArbitrary id (id :: Int -> Int)
-inverseFunctionsOnArbitrary
-    :: (Show a, Eq a, Arbitrary a)
-    => (a -> b) -> (b -> a) -> Property
-inverseFunctionsOnArbitrary f g = inverseFunctionsOnGen f g arbitrary
+inverseFunctionsOnArbitrary ::
+       (Show a, Eq a, Arbitrary a) => (a -> b) -> (b -> a) -> Property
+inverseFunctionsOnArbitrary f g = inverseFunctionsOnGen f g arbitrary shrink
 
-inverseFunctionsIfFirstSucceedsOnGen
-    :: (Show a, Eq a, CanFail f)
-    => (a -> f b) -> (b -> a) -> Gen a -> Property
-inverseFunctionsIfFirstSucceedsOnGen f g gen =
-    forAll gen $ \a ->
+inverseFunctionsIfFirstSucceedsOnGen ::
+       (Show a, Eq a, CanFail f)
+    => (a -> f b)
+    -> (b -> a)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+inverseFunctionsIfFirstSucceedsOnGen f g gen s =
+    forAllShrink gen s $ \a ->
         case resultIfSucceeded (f a) of
             Nothing -> return () -- fine
             Just b -> g b `shouldBe` a
 
-inverseFunctionsIfFirstSucceedsOnValid
-    :: (Show a, Eq a, GenValid a, CanFail f)
-    => (a -> f b) -> (b -> a) -> Property
+inverseFunctionsIfFirstSucceedsOnValid ::
+       (Show a, Eq a, GenValid a, CanFail f)
+    => (a -> f b)
+    -> (b -> a)
+    -> Property
 inverseFunctionsIfFirstSucceedsOnValid f g =
-    inverseFunctionsIfFirstSucceedsOnGen f g genValid
+    inverseFunctionsIfFirstSucceedsOnGen f g genValid shrinkValid
 
-inverseFunctionsIfFirstSucceeds
-    :: (Show a, Eq a, GenUnchecked a, CanFail f)
-    => (a -> f b) -> (b -> a) -> Property
+inverseFunctionsIfFirstSucceeds ::
+       (Show a, Eq a, GenUnchecked a, CanFail f)
+    => (a -> f b)
+    -> (b -> a)
+    -> Property
 inverseFunctionsIfFirstSucceeds f g =
-    inverseFunctionsIfFirstSucceedsOnGen f g genUnchecked
+    inverseFunctionsIfFirstSucceedsOnGen f g genUnchecked shrinkUnchecked
 
-inverseFunctionsIfFirstSucceedsOnArbitrary
-    :: (Show a, Eq a, Arbitrary a, CanFail f)
-    => (a -> f b) -> (b -> a) -> Property
+inverseFunctionsIfFirstSucceedsOnArbitrary ::
+       (Show a, Eq a, Arbitrary a, CanFail f)
+    => (a -> f b)
+    -> (b -> a)
+    -> Property
 inverseFunctionsIfFirstSucceedsOnArbitrary f g =
-    inverseFunctionsIfFirstSucceedsOnGen f g arbitrary
+    inverseFunctionsIfFirstSucceedsOnGen f g arbitrary shrink
 
-inverseFunctionsIfSecondSucceedsOnGen
-    :: (Show a, Eq a, CanFail f)
-    => (a -> b) -> (b -> f a) -> Gen a -> Property
-inverseFunctionsIfSecondSucceedsOnGen f g gen =
-    forAll gen $ \a ->
+inverseFunctionsIfSecondSucceedsOnGen ::
+       (Show a, Eq a, CanFail f)
+    => (a -> b)
+    -> (b -> f a)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+inverseFunctionsIfSecondSucceedsOnGen f g gen s =
+    forAllShrink gen s $ \a ->
         case resultIfSucceeded (g (f a)) of
             Nothing -> return () -- fine
             Just r -> r `shouldBe` a
 
-inverseFunctionsIfSecondSucceedsOnValid
-    :: (Show a, Eq a, GenValid a, CanFail f)
-    => (a -> b) -> (b -> f a) -> Property
+inverseFunctionsIfSecondSucceedsOnValid ::
+       (Show a, Eq a, GenValid a, CanFail f)
+    => (a -> b)
+    -> (b -> f a)
+    -> Property
 inverseFunctionsIfSecondSucceedsOnValid f g =
-    inverseFunctionsIfSecondSucceedsOnGen f g genValid
+    inverseFunctionsIfSecondSucceedsOnGen f g genValid shrinkValid
 
-inverseFunctionsIfSecondSucceeds
-    :: (Show a, Eq a, GenUnchecked a, CanFail f)
-    => (a -> b) -> (b -> f a) -> Property
+inverseFunctionsIfSecondSucceeds ::
+       (Show a, Eq a, GenUnchecked a, CanFail f)
+    => (a -> b)
+    -> (b -> f a)
+    -> Property
 inverseFunctionsIfSecondSucceeds f g =
-    inverseFunctionsIfSecondSucceedsOnGen f g genUnchecked
+    inverseFunctionsIfSecondSucceedsOnGen f g genUnchecked shrinkUnchecked
 
-inverseFunctionsIfSecondSucceedsOnArbitrary
-    :: (Show a, Eq a, Arbitrary a, CanFail f)
-    => (a -> b) -> (b -> f a) -> Property
+inverseFunctionsIfSecondSucceedsOnArbitrary ::
+       (Show a, Eq a, Arbitrary a, CanFail f)
+    => (a -> b)
+    -> (b -> f a)
+    -> Property
 inverseFunctionsIfSecondSucceedsOnArbitrary f g =
-    inverseFunctionsIfSecondSucceedsOnGen f g arbitrary
+    inverseFunctionsIfSecondSucceedsOnGen f g arbitrary shrink
 
-inverseFunctionsIfSucceedOnGen
-    :: (Show a, Eq a, CanFail f, CanFail g)
-    => (a -> f b) -> (b -> g a) -> Gen a -> Property
-inverseFunctionsIfSucceedOnGen f g gen =
-    forAll gen $ \a ->
+inverseFunctionsIfSucceedOnGen ::
+       (Show a, Eq a, CanFail f, CanFail g)
+    => (a -> f b)
+    -> (b -> g a)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+inverseFunctionsIfSucceedOnGen f g gen s =
+    forAllShrink gen s $ \a ->
         case do fa <- resultIfSucceeded $ f a
                 resultIfSucceeded $ g fa of
             Nothing -> return () -- fine
             Just r -> r `shouldBe` a
 
-inverseFunctionsIfSucceedOnValid
-    :: (Show a, Eq a, GenValid a, CanFail f, CanFail g)
-    => (a -> f b) -> (b -> g a) -> Property
+inverseFunctionsIfSucceedOnValid ::
+       (Show a, Eq a, GenValid a, CanFail f, CanFail g)
+    => (a -> f b)
+    -> (b -> g a)
+    -> Property
 inverseFunctionsIfSucceedOnValid f g =
-    inverseFunctionsIfSucceedOnGen f g genValid
+    inverseFunctionsIfSucceedOnGen f g genValid shrinkValid
 
-inverseFunctionsIfSucceed
-    :: (Show a, Eq a, GenUnchecked a, CanFail f, CanFail g)
-    => (a -> f b) -> (b -> g a) -> Property
-inverseFunctionsIfSucceed f g = inverseFunctionsIfSucceedOnGen f g genUnchecked
+inverseFunctionsIfSucceed ::
+       (Show a, Eq a, GenUnchecked a, CanFail f, CanFail g)
+    => (a -> f b)
+    -> (b -> g a)
+    -> Property
+inverseFunctionsIfSucceed f g =
+    inverseFunctionsIfSucceedOnGen f g genUnchecked shrinkUnchecked
 
-inverseFunctionsIfSucceedOnArbitrary
-    :: (Show a, Eq a, Arbitrary a, CanFail f, CanFail g)
-    => (a -> f b) -> (b -> g a) -> Property
+inverseFunctionsIfSucceedOnArbitrary ::
+       (Show a, Eq a, Arbitrary a, CanFail f, CanFail g)
+    => (a -> f b)
+    -> (b -> g a)
+    -> Property
 inverseFunctionsIfSucceedOnArbitrary f g =
-    inverseFunctionsIfSucceedOnGen f g arbitrary
+    inverseFunctionsIfSucceedOnGen f g arbitrary shrink
diff --git a/src/Test/Validity/Functions/Validity.hs b/src/Test/Validity/Functions/Validity.hs
--- a/src/Test/Validity/Functions/Validity.hs
+++ b/src/Test/Validity/Functions/Validity.hs
@@ -24,61 +24,71 @@
 
 -- | 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
+producesValidsOnGen ::
+       (Show a, Show b, Validity b)
+    => (a -> b)
+    -> Gen a
+    -> (a -> [a])
+    -> Property
+producesValidsOnGen func gen s =
+    forAllShrink gen s $ \a -> func a `shouldSatisfy` isValid
 
 -- | The function produces valid output when the input is generated by
 -- @genValid@
-producesValidsOnValids
-    :: (Show a, Show b, GenValid a, Validity b)
-    => (a -> b) -> Property
-producesValidsOnValids = (`producesValidsOnGen` genValid)
+producesValidsOnValids ::
+       (Show a, Show b, GenValid a, Validity b) => (a -> b) -> Property
+producesValidsOnValids f = producesValidsOnGen f genValid shrinkValid
 
 -- | The function produces valid output when the input is generated by
 -- @genUnchecked@
-producesValid
-    :: (Show a, Show b, GenUnchecked a, Validity b)
-    => (a -> b) -> Property
-producesValid = (`producesValidsOnGen` genUnchecked)
+producesValid ::
+       (Show a, Show b, GenUnchecked a, Validity b) => (a -> b) -> Property
+producesValid f = producesValidsOnGen f genUnchecked shrinkUnchecked
 
 -- | The function produces valid output when the input is generated by
 -- @arbitrary@
-producesValidsOnArbitrary
-    :: (Show a, Show b, Arbitrary a, Validity b)
-    => (a -> b) -> Property
-producesValidsOnArbitrary = (`producesValidsOnGen` arbitrary)
+producesValidsOnArbitrary ::
+       (Show a, Show b, Arbitrary a, Validity b) => (a -> b) -> Property
+producesValidsOnArbitrary f = producesValidsOnGen f arbitrary shrink
 
-producesValidsOnGens2
-    :: (Show a, Show b, Show c, Validity c)
-    => (a -> b -> c) -> Gen (a, b) -> Property
-producesValidsOnGens2 func gen =
-    forAll gen $ \(a, b) -> func a b `shouldSatisfy` isValid
+producesValidsOnGens2 ::
+       (Show a, Show b, Show c, Validity c)
+    => (a -> b -> c)
+    -> Gen (a, b)
+    -> ((a, b) -> [(a, b)])
+    -> Property
+producesValidsOnGens2 func gen s =
+    forAllShrink gen s $ \(a, b) -> func a b `shouldSatisfy` isValid
 
-producesValidsOnValids2
-    :: (Show a, Show b, Show c, GenValid a, GenValid b, Validity c)
-    => (a -> b -> c) -> Property
-producesValidsOnValids2 func = producesValidsOnGens2 func genValid
+producesValidsOnValids2 ::
+       (Show a, Show b, Show c, GenValid a, GenValid b, Validity c)
+    => (a -> b -> c)
+    -> Property
+producesValidsOnValids2 func = producesValidsOnGens2 func genValid shrinkValid
 
-producesValid2
-    :: (Show a, Show b, Show c, GenUnchecked a, GenUnchecked b, Validity c)
-    => (a -> b -> c) -> Property
-producesValid2 func = producesValidsOnGens2 func genUnchecked
+producesValid2 ::
+       (Show a, Show b, Show c, GenUnchecked a, GenUnchecked b, Validity c)
+    => (a -> b -> c)
+    -> Property
+producesValid2 func = producesValidsOnGens2 func genUnchecked shrinkUnchecked
 
-producesValidsOnArbitrary2
-    :: (Show a, Show b, Show c, Arbitrary a, Arbitrary b, Validity c)
-    => (a -> b -> c) -> Property
-producesValidsOnArbitrary2 func = producesValidsOnGens2 func arbitrary
+producesValidsOnArbitrary2 ::
+       (Show a, Show b, Show c, Arbitrary a, Arbitrary b, Validity c)
+    => (a -> b -> c)
+    -> Property
+producesValidsOnArbitrary2 func = producesValidsOnGens2 func arbitrary shrink
 
-producesValidsOnGens3
-    :: (Show a, Show b, Show c, Show d, Validity d)
-    => (a -> b -> c -> d) -> Gen (a, b, c) -> Property
-producesValidsOnGens3 func gen =
-    forAll gen $ \(a, b, c) -> func a b c `shouldSatisfy` isValid
+producesValidsOnGens3 ::
+       (Show a, Show b, Show c, Show d, Validity d)
+    => (a -> b -> c -> d)
+    -> Gen (a, b, c)
+    -> ((a, b, c) -> [(a, b, c)])
+    -> Property
+producesValidsOnGens3 func gen s =
+    forAllShrink gen s $ \(a, b, c) -> func a b c `shouldSatisfy` isValid
 
-producesValidsOnValids3
-    :: ( Show a
+producesValidsOnValids3 ::
+       ( Show a
        , Show b
        , Show c
        , Show d
@@ -87,11 +97,12 @@
        , GenValid c
        , Validity d
        )
-    => (a -> b -> c -> d) -> Property
-producesValidsOnValids3 func = producesValidsOnGens3 func genValid
+    => (a -> b -> c -> d)
+    -> Property
+producesValidsOnValids3 func = producesValidsOnGens3 func genValid shrinkValid
 
-producesValid3
-    :: ( Show a
+producesValid3 ::
+       ( Show a
        , Show b
        , Show c
        , Show d
@@ -100,11 +111,12 @@
        , GenUnchecked c
        , Validity d
        )
-    => (a -> b -> c -> d) -> Property
-producesValid3 func = producesValidsOnGens3 func genUnchecked
+    => (a -> b -> c -> d)
+    -> Property
+producesValid3 func = producesValidsOnGens3 func genUnchecked shrinkUnchecked
 
-producesValidsOnArbitrary3
-    :: ( Show a
+producesValidsOnArbitrary3 ::
+       ( Show a
        , Show b
        , Show c
        , Show d
@@ -113,5 +125,6 @@
        , Arbitrary c
        , Validity d
        )
-    => (a -> b -> c -> d) -> Property
-producesValidsOnArbitrary3 func = producesValidsOnGens3 func arbitrary
+    => (a -> b -> c -> d)
+    -> Property
+producesValidsOnArbitrary3 func = producesValidsOnGens3 func arbitrary shrink
diff --git a/src/Test/Validity/GenValidity/Property.hs b/src/Test/Validity/GenValidity/Property.hs
--- a/src/Test/Validity/GenValidity/Property.hs
+++ b/src/Test/Validity/GenValidity/Property.hs
@@ -8,25 +8,23 @@
     , genGeneratesInvalid
     ) where
 
-import Data.Data
-
 import Data.GenValidity
 
 import Test.Hspec
 import Test.QuickCheck
 
-import Test.Validity.Property.Utils
-
 -- | The given generator generates only valid data points
-genGeneratesValid
-    :: forall a.
-       (Show a, Validity a)
-    => Gen a -> Property
-genGeneratesValid gen = forAll gen (`shouldSatisfy` isValid)
+genGeneratesValid ::
+       forall a. (Show a, Validity a)
+    => Gen a
+    -> (a -> [a])
+    -> Property
+genGeneratesValid gen s = forAllShrink gen s (`shouldSatisfy` isValid)
 
 -- | The given generator generates only invalid data points
-genGeneratesInvalid
-    :: forall a.
-       (Show a, Validity a)
-    => Gen a -> Property
-genGeneratesInvalid gen = forAll gen (`shouldSatisfy` isInvalid)
+genGeneratesInvalid ::
+       forall a. (Show a, Validity a)
+    => Gen a
+    -> (a -> [a])
+    -> Property
+genGeneratesInvalid gen s = forAllShrink gen s (`shouldSatisfy` isInvalid)
diff --git a/src/Test/Validity/Operations/Associativity.hs b/src/Test/Validity/Operations/Associativity.hs
--- a/src/Test/Validity/Operations/Associativity.hs
+++ b/src/Test/Validity/Operations/Associativity.hs
@@ -13,32 +13,38 @@
 import Test.Hspec
 import Test.QuickCheck
 
-associativeOnGens
-    :: (Show a, Eq a)
-    => (a -> a -> a) -> Gen (a, a, a) -> Property
-associativeOnGens op gen =
-    forAll gen $ \(a, b, c) ->
+-- |
+--
+-- \[
+--     Associative(\star)
+--     \quad\equiv\quad
+--     \forall a, b, c:
+--     (a \star b) \star c = a \star (b \star c)
+-- \]
+associativeOnGens ::
+       (Show a, Eq a)
+    => (a -> a -> a)
+    -> Gen (a, a, a)
+    -> ((a, a, a) -> [(a, a, a)])
+    -> Property
+associativeOnGens op gen s =
+    forAllShrink gen s $ \(a, b, c) ->
         ((a `op` b) `op` c) `shouldBe` (a `op` (b `op` c))
 
-associativeOnValids
-    :: (Show a, Eq a, GenValid a)
-    => (a -> a -> a) -> Property
-associativeOnValids op = associativeOnGens op genValid
+associativeOnValids :: (Show a, Eq a, GenValid a) => (a -> a -> a) -> Property
+associativeOnValids op = associativeOnGens op genValid shrinkValid
 
 -- |
 --
 -- prop> associative ((*) :: Int -> Int -> Int)
 -- prop> associative ((+) :: Int -> Int -> Int)
-associative
-    :: (Show a, Eq a, GenUnchecked a)
-    => (a -> a -> a) -> Property
-associative op = associativeOnGens op genUnchecked
+associative :: (Show a, Eq a, GenUnchecked a) => (a -> a -> a) -> Property
+associative op = associativeOnGens op genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> associativeOnArbitrary ((*) :: Int -> Int -> Int)
 -- prop> associativeOnArbitrary ((+) :: Int -> Int -> Int)
-associativeOnArbitrary
-    :: (Show a, Eq a, Arbitrary a)
-    => (a -> a -> a) -> Property
-associativeOnArbitrary op = associativeOnGens op arbitrary
+associativeOnArbitrary ::
+       (Show a, Eq a, Arbitrary a) => (a -> a -> a) -> Property
+associativeOnArbitrary op = associativeOnGens op arbitrary shrink
diff --git a/src/Test/Validity/Operations/Commutativity.hs b/src/Test/Validity/Operations/Commutativity.hs
--- a/src/Test/Validity/Operations/Commutativity.hs
+++ b/src/Test/Validity/Operations/Commutativity.hs
@@ -13,35 +13,41 @@
 import Test.Hspec
 import Test.QuickCheck
 
-commutativeOnGens
-    :: (Show a, Eq a)
-    => (a -> a -> a) -> Gen (a, a) -> Property
-commutativeOnGens op gen =
-    forAll gen $ \(a, b) -> (a `op` b) `shouldBe` (b `op` a)
+-- |
+--
+-- \[
+--     Commutative(\star)
+--     \quad\equiv\quad
+--     \forall a, b:
+--     a \star b = b \star a
+-- \]
+commutativeOnGens ::
+       (Show a, Eq a)
+    => (a -> a -> a)
+    -> Gen (a, a)
+    -> ((a, a) -> [(a, a)])
+    -> Property
+commutativeOnGens op gen s =
+    forAllShrink gen s $ \(a, b) -> (a `op` b) `shouldBe` (b `op` a)
 
 -- |
 --
 -- prop> commutative ((+) :: Double -> Double -> Double)
 -- prop> commutative ((*) :: Double -> Double -> Double)
-commutativeOnValids
-    :: (Show a, Eq a, GenValid a)
-    => (a -> a -> a) -> Property
-commutativeOnValids op = commutativeOnGens op genValid
+commutativeOnValids :: (Show a, Eq a, GenValid a) => (a -> a -> a) -> Property
+commutativeOnValids op = commutativeOnGens op genValid shrinkValid
 
 -- |
 --
 -- prop> commutative ((+) :: Int -> Int -> Int)
 -- prop> commutative ((*) :: Int -> Int -> Int)
-commutative
-    :: (Show a, Eq a, GenUnchecked a)
-    => (a -> a -> a) -> Property
-commutative op = commutativeOnGens op genUnchecked
+commutative :: (Show a, Eq a, GenUnchecked a) => (a -> a -> a) -> Property
+commutative op = commutativeOnGens op genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> commutativeOnArbitrary ((+) :: Int -> Int -> Int)
 -- prop> commutativeOnArbitrary ((*) :: Int -> Int -> Int)
-commutativeOnArbitrary
-    :: (Show a, Eq a, Arbitrary a)
-    => (a -> a -> a) -> Property
-commutativeOnArbitrary op = commutativeOnGens op arbitrary
+commutativeOnArbitrary ::
+       (Show a, Eq a, Arbitrary a) => (a -> a -> a) -> Property
+commutativeOnArbitrary op = commutativeOnGens op arbitrary shrink
diff --git a/src/Test/Validity/Operations/Identity.hs b/src/Test/Validity/Operations/Identity.hs
--- a/src/Test/Validity/Operations/Identity.hs
+++ b/src/Test/Validity/Operations/Identity.hs
@@ -31,55 +31,53 @@
 --   \quad\equiv\quad
 --   \forall a: (b \star a) \doteq a
 -- \]
-leftIdentityOnElemWithEquality
-    :: (b -> a -> a) -- ^ A binary operation
+leftIdentityOnElemWithEquality ::
+       (b -> a -> a) -- ^ A binary operation
     -> (a -> a -> Bool) -- ^ An equality
     -> b -- ^ A candidate left-identity
     -> a -- ^ An element
     -> Bool
 leftIdentityOnElemWithEquality op eq b a = (b `op` a) `eq` a
 
-leftIdentityOnGenWithEquality
-    :: Show a
+leftIdentityOnGenWithEquality ::
+       Show a
     => (b -> a -> a) -- ^ A binary operation
     -> (a -> a -> Bool) -- ^ An equality
     -> b -- ^ A candidate left-identity
     -> Gen a
+    -> (a -> [a])
     -> Property
-leftIdentityOnGenWithEquality op eq b gen =
-    forAll gen $ leftIdentityOnElemWithEquality op eq b
+leftIdentityOnGenWithEquality op eq b gen s =
+    forAllShrink gen s $ leftIdentityOnElemWithEquality op eq b
 
-leftIdentityOnGen
-    :: (Show a, Eq a)
+leftIdentityOnGen ::
+       (Show a, Eq a)
     => (b -> a -> a) -- ^ A binary operation
     -> b -- ^ A candidate left-identity
     -> Gen a
+    -> (a -> [a])
     -> Property
 leftIdentityOnGen op = leftIdentityOnGenWithEquality op (==)
 
 -- |
 --
 -- prop> leftIdentityOnValid (flip ((^) :: Double -> Int -> Double)) 1
-leftIdentityOnValid
-    :: (Show a, Eq a, GenValid a)
-    => (b -> a -> a) -> b -> Property
-leftIdentityOnValid op b = leftIdentityOnGen op b genValid
+leftIdentityOnValid ::
+       (Show a, Eq a, GenValid a) => (b -> a -> a) -> b -> Property
+leftIdentityOnValid op b = leftIdentityOnGen op b genValid shrinkValid
 
 -- |
 --
 -- prop> leftIdentity (flip ((^) :: Int -> Int -> Int)) 1
-leftIdentity
-    :: (Show a, Eq a, GenUnchecked a)
-    => (b -> a -> a) -> b -> Property
-leftIdentity op b = leftIdentityOnGen op b genUnchecked
+leftIdentity :: (Show a, Eq a, GenUnchecked a) => (b -> a -> a) -> b -> Property
+leftIdentity op b = leftIdentityOnGen op b genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> leftIdentityOnArbitrary (flip ((^) :: Int -> Int -> Int)) 1
-leftIdentityOnArbitrary
-    :: (Show a, Eq a, Arbitrary a)
-    => (b -> a -> a) -> b -> Property
-leftIdentityOnArbitrary op b = leftIdentityOnGen op b arbitrary
+leftIdentityOnArbitrary ::
+       (Show a, Eq a, Arbitrary a) => (b -> a -> a) -> b -> Property
+leftIdentityOnArbitrary op b = leftIdentityOnGen op b arbitrary shrink
 
 -- |
 --
@@ -88,85 +86,85 @@
 --   \quad\equiv\quad
 --   \forall a: (a \star b) \doteq a
 -- \]
-rightIdentityOnElemWithEquality
-    :: (a -> b -> a) -- ^ A binary operation
+rightIdentityOnElemWithEquality ::
+       (a -> b -> a) -- ^ A binary operation
     -> (a -> a -> Bool) -- ^ An equality
     -> b -- ^ A candidate right-identity
     -> a -- ^ An element
     -> Bool
 rightIdentityOnElemWithEquality op eq b a = (a `op` b) `eq` a
 
-rightIdentityOnGenWithEquality
-    :: Show a
+rightIdentityOnGenWithEquality ::
+       Show a
     => (a -> b -> a) -- ^ A binary operation
     -> (a -> a -> Bool) -- ^ An equality
     -> b -- ^ A candidate right-identity
     -> Gen a
+    -> (a -> [a])
     -> Property
-rightIdentityOnGenWithEquality op eq b gen =
-    forAll gen $ rightIdentityOnElemWithEquality op eq b
+rightIdentityOnGenWithEquality op eq b gen s =
+    forAllShrink gen s $ rightIdentityOnElemWithEquality op eq b
 
-rightIdentityOnGen
-    :: (Show a, Eq a)
+rightIdentityOnGen ::
+       (Show a, Eq a)
     => (a -> b -> a) -- ^ A binary operation
     -> b -- ^ A candidate right-identity
     -> Gen a
+    -> (a -> [a])
     -> Property
 rightIdentityOnGen op = rightIdentityOnGenWithEquality op (==)
 
 -- |
 --
 -- prop> rightIdentityOnValid ((^) :: Double -> Int -> Double) 1
-rightIdentityOnValid
-    :: (Show a, Eq a, GenValid a)
-    => (a -> b -> a) -> b -> Property
-rightIdentityOnValid op b = rightIdentityOnGen op b genValid
+rightIdentityOnValid ::
+       (Show a, Eq a, GenValid a) => (a -> b -> a) -> b -> Property
+rightIdentityOnValid op b = rightIdentityOnGen op b genValid shrinkValid
 
 -- |
 --
 -- prop> rightIdentity ((^) :: Int -> Int -> Int) 1
-rightIdentity
-    :: (Show a, Eq a, GenUnchecked a)
-    => (a -> b -> a) -> b -> Property
-rightIdentity op b = rightIdentityOnGen op b genUnchecked
+rightIdentity ::
+       (Show a, Eq a, GenUnchecked a) => (a -> b -> a) -> b -> Property
+rightIdentity op b = rightIdentityOnGen op b genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> rightIdentityOnArbitrary ((^) :: Int -> Int -> Int) 1
-rightIdentityOnArbitrary
-    :: (Show a, Eq a, Arbitrary a)
-    => (a -> b -> a) -> b -> Property
-rightIdentityOnArbitrary op b = rightIdentityOnGen op b arbitrary
+rightIdentityOnArbitrary ::
+       (Show a, Eq a, Arbitrary a) => (a -> b -> a) -> b -> Property
+rightIdentityOnArbitrary op b = rightIdentityOnGen op b arbitrary shrink
 
-identityOnGen
-    :: (Show a, Eq a)
-    => (a -> a -> a) -> a -> Gen a -> Property
-identityOnGen op e gen =
-    leftIdentityOnGen op e gen .&&. rightIdentityOnGen op e gen
+-- |
+--
+-- \[
+--   Identity(\star, \doteq, b)
+--   \quad\equiv\quad
+--   LeftIdentity(\star, \doteq, b) \wedge RightIdentity(\star, \doteq, b)
+-- \]
+identityOnGen ::
+       (Show a, Eq a) => (a -> a -> a) -> a -> Gen a -> (a -> [a]) -> Property
+identityOnGen op e gen s =
+    leftIdentityOnGen op e gen s .&&. rightIdentityOnGen op e gen s
 
 -- |
 --
 -- prop> identityOnValid ((*) :: Double -> Double -> Double) 1
 -- prop> identityOnValid ((+) :: Double -> Double -> Double) 0
-identityOnValid
-    :: (Show a, Eq a, GenValid a)
-    => (a -> a -> a) -> a -> Property
-identityOnValid op a = identityOnGen op a genValid
+identityOnValid :: (Show a, Eq a, GenValid a) => (a -> a -> a) -> a -> Property
+identityOnValid op a = identityOnGen op a genValid shrinkValid
 
 -- |
 --
 -- prop> identity ((*) :: Int -> Int -> Int) 1
 -- prop> identity ((+) :: Int -> Int -> Int) 0
-identity
-    :: (Show a, Eq a, GenUnchecked a)
-    => (a -> a -> a) -> a -> Property
-identity op e = identityOnGen op e genUnchecked
+identity :: (Show a, Eq a, GenUnchecked a) => (a -> a -> a) -> a -> Property
+identity op e = identityOnGen op e genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> identityOnArbitrary ((*) :: Int -> Int -> Int) 1
 -- prop> identityOnArbitrary ((+) :: Int -> Int -> Int) 0
-identityOnArbitrary
-    :: (Show a, Eq a, Arbitrary a)
-    => (a -> a -> a) -> a -> Property
-identityOnArbitrary op a = identityOnGen op a arbitrary
+identityOnArbitrary ::
+       (Show a, Eq a, Arbitrary a) => (a -> a -> a) -> a -> Property
+identityOnArbitrary op a = identityOnGen op a arbitrary shrink
diff --git a/src/Test/Validity/Property.hs b/src/Test/Validity/Property.hs
--- a/src/Test/Validity/Property.hs
+++ b/src/Test/Validity/Property.hs
@@ -3,6 +3,9 @@
 
 module Test.Validity.Property
     ( module Data.GenValidity
+    , forAllUnchecked
+    , forAllValid
+    , forAllInvalid
       -- * Tests for GenValidity instances
     , genGeneratesValid
     , genGeneratesInvalid
@@ -190,3 +193,4 @@
 import Test.Validity.Operations
 import Test.Validity.Relations
 import Test.Validity.Types
+import Test.Validity.Property.Utils
diff --git a/src/Test/Validity/Property/Utils.hs b/src/Test/Validity/Property/Utils.hs
--- a/src/Test/Validity/Property/Utils.hs
+++ b/src/Test/Validity/Property/Utils.hs
@@ -1,9 +1,25 @@
 module Test.Validity.Property.Utils
-    ( (<==>)
+    ( forAllUnchecked
+    , forAllValid
+    , forAllInvalid
+    , (<==>)
     , (===>)
     ) where
 
-import Data.Data
+import Test.QuickCheck
+
+import Data.GenValidity
+
+forAllUnchecked ::
+       (Show a, GenUnchecked a, Testable prop) => (a -> prop) -> Property
+forAllUnchecked = forAllShrink genUnchecked shrinkUnchecked
+
+forAllValid :: (Show a, GenValid a, Testable prop) => (a -> prop) -> Property
+forAllValid = forAllShrink genValid shrinkValid
+
+forAllInvalid ::
+       (Show a, GenInvalid a, Testable prop) => (a -> prop) -> Property
+forAllInvalid = forAllShrink genInvalid shrinkInvalid
 
 (===>) :: Bool -> Bool -> Bool
 (===>) a b = not a || b
diff --git a/src/Test/Validity/Relations/Antireflexivity.hs b/src/Test/Validity/Relations/Antireflexivity.hs
--- a/src/Test/Validity/Relations/Antireflexivity.hs
+++ b/src/Test/Validity/Relations/Antireflexivity.hs
@@ -20,43 +20,37 @@
 --   \quad\equiv\quad
 --   \forall a: \neg (a \prec a)
 -- \]
-antireflexiveOnElem
-    :: (a -> a -> Bool) -- ^ A relation
+antireflexiveOnElem ::
+       (a -> a -> Bool) -- ^ A relation
     -> a -- ^ An element
     -> Bool
 antireflexiveOnElem func a = not $ func a a
 
-antireflexivityOnGen
-    :: Show a
-    => (a -> a -> Bool) -> Gen a -> Property
-antireflexivityOnGen func gen = forAll gen $ antireflexiveOnElem func
+antireflexivityOnGen ::
+       Show a => (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
+antireflexivityOnGen func gen s = forAllShrink gen s $ antireflexiveOnElem func
 
 -- |
 --
 -- prop> antireflexivityOnValid ((<) :: Double -> Double -> Bool)
 -- prop> antireflexivityOnValid ((/=) :: Double -> Double -> Bool)
 -- prop> antireflexivityOnValid ((>) :: Double -> Double -> Bool)
-antireflexivityOnValid
-    :: (Show a, GenValid a)
-    => (a -> a -> Bool) -> Property
-antireflexivityOnValid func = antireflexivityOnGen func genValid
+antireflexivityOnValid :: (Show a, GenValid a) => (a -> a -> Bool) -> Property
+antireflexivityOnValid func = antireflexivityOnGen func genValid shrinkValid
 
 -- |
 --
 -- prop> antireflexivity ((<) :: Int -> Int -> Bool)
 -- prop> antireflexivity ((/=) :: Int -> Int -> Bool)
 -- prop> antireflexivity ((>) :: Int -> Int -> Bool)
-antireflexivity
-    :: (Show a, GenUnchecked a)
-    => (a -> a -> Bool) -> Property
-antireflexivity func = antireflexivityOnGen func genUnchecked
+antireflexivity :: (Show a, GenUnchecked a) => (a -> a -> Bool) -> Property
+antireflexivity func = antireflexivityOnGen func genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> antireflexivityOnArbitrary ((<) :: Int -> Int -> Bool)
 -- prop> antireflexivityOnArbitrary ((/=) :: Int -> Int -> Bool)
 -- prop> antireflexivityOnArbitrary ((>) :: Int -> Int -> Bool)
-antireflexivityOnArbitrary
-    :: (Show a, Arbitrary a)
-    => (a -> a -> Bool) -> Property
-antireflexivityOnArbitrary func = antireflexivityOnGen func arbitrary
+antireflexivityOnArbitrary ::
+       (Show a, Arbitrary a) => (a -> a -> Bool) -> Property
+antireflexivityOnArbitrary func = antireflexivityOnGen func arbitrary shrink
diff --git a/src/Test/Validity/Relations/Antisymmetry.hs b/src/Test/Validity/Relations/Antisymmetry.hs
--- a/src/Test/Validity/Relations/Antisymmetry.hs
+++ b/src/Test/Validity/Relations/Antisymmetry.hs
@@ -23,8 +23,8 @@
 --   \quad\equiv\quad
 --   \forall a, b: ((a \prec b) \wedge (b \prec a)) \Rightarrow (a \doteq b)
 -- \]
-antisymmetricOnElemsWithEquality
-    :: (a -> a -> Bool) -- ^ A relation
+antisymmetricOnElemsWithEquality ::
+       (a -> a -> Bool) -- ^ A relation
     -> (a -> a -> Bool) -- ^ An equivalence relation
     -> a
     -> a -- ^ Two elements
@@ -32,15 +32,23 @@
 antisymmetricOnElemsWithEquality func eq a b =
     (func a b && func b a) ===> (a `eq` b)
 
-antisymmetryOnGensWithEquality
-    :: Show a
-    => (a -> a -> Bool) -> Gen (a, a) -> (a -> a -> Bool) -> Property
-antisymmetryOnGensWithEquality func gen eq =
-    forAll gen $ uncurry $ antisymmetricOnElemsWithEquality func eq
+antisymmetryOnGensWithEquality ::
+       Show a
+    => (a -> a -> Bool)
+    -> Gen (a, a)
+    -> (a -> a -> Bool)
+    -> (a -> [a])
+    -> Property
+antisymmetryOnGensWithEquality func gen eq s =
+    forAllShrink gen (shrinkT2 s) $
+    uncurry $ antisymmetricOnElemsWithEquality func eq
 
-antisymmetryOnGens
-    :: (Show a, Eq a)
-    => (a -> a -> Bool) -> Gen (a, a) -> Property
+antisymmetryOnGens ::
+       (Show a, Eq a)
+    => (a -> a -> Bool)
+    -> Gen (a, a)
+    -> (a -> [a])
+    -> Property
 antisymmetryOnGens func gen = antisymmetryOnGensWithEquality func gen (==)
 
 -- |
@@ -52,10 +60,9 @@
 -- prop> antisymmetryOnValid (Data.List.isPrefixOf :: [Double] -> [Double] -> Bool)
 -- prop> antisymmetryOnValid (Data.List.isSuffixOf :: [Double] -> [Double] -> Bool)
 -- prop> antisymmetryOnValid (Data.List.isInfixOf :: [Double] -> [Double] -> Bool)
-antisymmetryOnValid
-    :: (Show a, Eq a, GenValid a)
-    => (a -> a -> Bool) -> Property
-antisymmetryOnValid func = antisymmetryOnGens func genValid
+antisymmetryOnValid ::
+       (Show a, Eq a, GenValid a) => (a -> a -> Bool) -> Property
+antisymmetryOnValid func = antisymmetryOnGens func genValid shrinkValid
 
 -- |
 --
@@ -67,10 +74,8 @@
 -- prop> antisymmetry (Data.List.isSuffixOf :: [Int] -> [Int] -> Bool)
 -- prop> antisymmetry (Data.List.isInfixOf :: [Int] -> [Int] -> Bool)
 -- prop> antisymmetry ((\x y -> even x && odd y) :: Int -> Int -> Bool)
-antisymmetry
-    :: (Show a, Eq a, GenUnchecked a)
-    => (a -> a -> Bool) -> Property
-antisymmetry func = antisymmetryOnGens func genUnchecked
+antisymmetry :: (Show a, Eq a, GenUnchecked a) => (a -> a -> Bool) -> Property
+antisymmetry func = antisymmetryOnGens func genUnchecked shrinkUnchecked
 
 -- |
 --
@@ -82,7 +87,6 @@
 -- prop> antisymmetryOnArbitrary (Data.List.isSuffixOf :: [Int] -> [Int] -> Bool)
 -- prop> antisymmetryOnArbitrary (Data.List.isInfixOf :: [Int] -> [Int] -> Bool)
 -- prop> antisymmetryOnArbitrary ((\x y -> even x && odd y) :: Int -> Int -> Bool)
-antisymmetryOnArbitrary
-    :: (Show a, Eq a, Arbitrary a)
-    => (a -> a -> Bool) -> Property
-antisymmetryOnArbitrary func = antisymmetryOnGens func arbitrary
+antisymmetryOnArbitrary ::
+       (Show a, Eq a, Arbitrary a) => (a -> a -> Bool) -> Property
+antisymmetryOnArbitrary func = antisymmetryOnGens func arbitrary shrink
diff --git a/src/Test/Validity/Relations/Reflexivity.hs b/src/Test/Validity/Relations/Reflexivity.hs
--- a/src/Test/Validity/Relations/Reflexivity.hs
+++ b/src/Test/Validity/Relations/Reflexivity.hs
@@ -20,16 +20,15 @@
 --   \quad\equiv\quad
 --   \forall a: (a \prec a)
 -- \]
-reflexiveOnElem
-    :: (a -> a -> Bool) -- ^ A relation
+reflexiveOnElem ::
+       (a -> a -> Bool) -- ^ A relation
     -> a -- ^ An element
     -> Bool
 reflexiveOnElem func a = func a a
 
-reflexivityOnGen
-    :: Show a
-    => (a -> a -> Bool) -> Gen a -> Property
-reflexivityOnGen func gen = forAll gen $ reflexiveOnElem func
+reflexivityOnGen ::
+       Show a => (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
+reflexivityOnGen func gen s = forAllShrink gen s $ reflexiveOnElem func
 
 -- |
 --
@@ -39,10 +38,8 @@
 -- prop> reflexivityOnValid (Data.List.isPrefixOf :: [Double] -> [Double] -> Bool)
 -- prop> reflexivityOnValid (Data.List.isSuffixOf :: [Double] -> [Double] -> Bool)
 -- prop> reflexivityOnValid (Data.List.isInfixOf :: [Double] -> [Double] -> Bool)
-reflexivityOnValid
-    :: (Show a, GenValid a)
-    => (a -> a -> Bool) -> Property
-reflexivityOnValid func = reflexivityOnGen func genValid
+reflexivityOnValid :: (Show a, GenValid a) => (a -> a -> Bool) -> Property
+reflexivityOnValid func = reflexivityOnGen func genValid shrinkValid
 
 -- |
 --
@@ -52,10 +49,8 @@
 -- prop> reflexivity (Data.List.isPrefixOf :: [Int] -> [Int] -> Bool)
 -- prop> reflexivity (Data.List.isSuffixOf :: [Int] -> [Int] -> Bool)
 -- prop> reflexivity (Data.List.isInfixOf :: [Int] -> [Int] -> Bool)
-reflexivity
-    :: (Show a, GenUnchecked a)
-    => (a -> a -> Bool) -> Property
-reflexivity func = reflexivityOnGen func genUnchecked
+reflexivity :: (Show a, GenUnchecked a) => (a -> a -> Bool) -> Property
+reflexivity func = reflexivityOnGen func genUnchecked shrinkUnchecked
 
 -- |
 --
@@ -65,7 +60,5 @@
 -- prop> reflexivityOnArbitrary (Data.List.isPrefixOf :: [Int] -> [Int] -> Bool)
 -- prop> reflexivityOnArbitrary (Data.List.isSuffixOf :: [Int] -> [Int] -> Bool)
 -- prop> reflexivityOnArbitrary (Data.List.isInfixOf :: [Int] -> [Int] -> Bool)
-reflexivityOnArbitrary
-    :: (Show a, Arbitrary a)
-    => (a -> a -> Bool) -> Property
-reflexivityOnArbitrary func = reflexivityOnGen func arbitrary
+reflexivityOnArbitrary :: (Show a, Arbitrary a) => (a -> a -> Bool) -> Property
+reflexivityOnArbitrary func = reflexivityOnGen func arbitrary shrink
diff --git a/src/Test/Validity/Relations/Symmetry.hs b/src/Test/Validity/Relations/Symmetry.hs
--- a/src/Test/Validity/Relations/Symmetry.hs
+++ b/src/Test/Validity/Relations/Symmetry.hs
@@ -22,41 +22,35 @@
 --   \quad\equiv\quad
 --   \forall a, b: (a \prec b) \Leftrightarrow (b \prec a)
 -- \]
-symmetricOnElems
-    :: (a -> a -> Bool) -- ^ A relation
+symmetricOnElems ::
+       (a -> a -> Bool) -- ^ A relation
     -> a
     -> a -- ^ Two elements
     -> Bool
 symmetricOnElems func a b = func a b <==> func b a
 
-symmetryOnGens
-    :: Show a
-    => (a -> a -> Bool) -> Gen (a, a) -> Property
-symmetryOnGens func gen = forAll gen $ uncurry $ symmetricOnElems func
+symmetryOnGens ::
+       Show a => (a -> a -> Bool) -> Gen (a, a) -> (a -> [a]) -> Property
+symmetryOnGens func gen s =
+    forAllShrink gen (shrinkT2 s) $ uncurry $ symmetricOnElems func
 
 -- |
 --
 -- prop> symmetryOnValid ((==) :: Double -> Double -> Bool)
 -- prop> symmetryOnValid ((/=) :: Double -> Double -> Bool)
-symmetryOnValid
-    :: (Show a, GenValid a)
-    => (a -> a -> Bool) -> Property
-symmetryOnValid func = symmetryOnGens func genValid
+symmetryOnValid :: (Show a, GenValid a) => (a -> a -> Bool) -> Property
+symmetryOnValid func = symmetryOnGens func genValid shrinkValid
 
 -- |
 --
 -- prop> symmetry ((==) :: Int -> Int -> Bool)
 -- prop> symmetry ((/=) :: Int -> Int -> Bool)
-symmetry
-    :: (Show a, GenUnchecked a)
-    => (a -> a -> Bool) -> Property
-symmetry func = symmetryOnGens func genUnchecked
+symmetry :: (Show a, GenUnchecked a) => (a -> a -> Bool) -> Property
+symmetry func = symmetryOnGens func genUnchecked shrinkUnchecked
 
 -- |
 --
 -- prop> symmetryOnArbitrary ((==) :: Int -> Int -> Bool)
 -- prop> symmetryOnArbitrary ((/=) :: Int -> Int -> Bool)
-symmetryOnArbitrary
-    :: (Show a, Arbitrary a)
-    => (a -> a -> Bool) -> Property
-symmetryOnArbitrary func = symmetryOnGens func arbitrary
+symmetryOnArbitrary :: (Show a, Arbitrary a) => (a -> a -> Bool) -> Property
+symmetryOnArbitrary func = symmetryOnGens func arbitrary shrink
diff --git a/src/Test/Validity/Relations/Transitivity.hs b/src/Test/Validity/Relations/Transitivity.hs
--- a/src/Test/Validity/Relations/Transitivity.hs
+++ b/src/Test/Validity/Relations/Transitivity.hs
@@ -22,19 +22,19 @@
 --   \quad\equiv\quad
 --   \forall a, b, c: ((a \prec b) \wedge (b \prec c)) \Rightarrow (a \prec c)
 -- \]
-transitiveOnElems
-    :: (a -> a -> Bool) -- ^ A relation
+transitiveOnElems ::
+       (a -> a -> Bool) -- ^ A relation
     -> a
     -> a
     -> a -- ^ Three elements
     -> Bool
 transitiveOnElems func a b c = (func a b && func b c) ===> func a c
 
-transitivityOnGens
-    :: Show a
-    => (a -> a -> Bool) -> Gen (a, a, a) -> Property
-transitivityOnGens func gen =
-    forAll gen $ \(a, b, c) -> transitiveOnElems func a b c
+transitivityOnGens ::
+       Show a => (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
+transitivityOnGens func gen s =
+    forAllShrink gen (shrinkT3 s) $ \(a, b, c) ->
+        transitiveOnElems func a b c
 
 -- |
 --
@@ -46,10 +46,8 @@
 -- prop> transitivityOnValid (Data.List.isPrefixOf :: [Double] -> [Double] -> Bool)
 -- prop> transitivityOnValid (Data.List.isSuffixOf :: [Double] -> [Double] -> Bool)
 -- prop> transitivityOnValid (Data.List.isInfixOf :: [Double] -> [Double] -> Bool)
-transitivityOnValid
-    :: (Show a, GenValid a)
-    => (a -> a -> Bool) -> Property
-transitivityOnValid func = transitivityOnGens func genValid
+transitivityOnValid :: (Show a, GenValid a) => (a -> a -> Bool) -> Property
+transitivityOnValid func = transitivityOnGens func genValid shrinkValid
 
 -- |
 --
@@ -61,10 +59,8 @@
 -- prop> transitivity (Data.List.isPrefixOf :: [Int] -> [Int] -> Bool)
 -- prop> transitivity (Data.List.isSuffixOf :: [Int] -> [Int] -> Bool)
 -- prop> transitivity (Data.List.isInfixOf :: [Int] -> [Int] -> Bool)
-transitivity
-    :: (Show a, GenUnchecked a)
-    => (a -> a -> Bool) -> Property
-transitivity func = transitivityOnGens func genUnchecked
+transitivity :: (Show a, GenUnchecked a) => (a -> a -> Bool) -> Property
+transitivity func = transitivityOnGens func genUnchecked shrinkUnchecked
 
 -- |
 --
@@ -76,7 +72,5 @@
 -- prop> transitivityOnArbitrary (Data.List.isPrefixOf :: [Int] -> [Int] -> Bool)
 -- prop> transitivityOnArbitrary (Data.List.isSuffixOf :: [Int] -> [Int] -> Bool)
 -- prop> transitivityOnArbitrary (Data.List.isInfixOf :: [Int] -> [Int] -> Bool)
-transitivityOnArbitrary
-    :: (Show a, Arbitrary a)
-    => (a -> a -> Bool) -> Property
-transitivityOnArbitrary func = transitivityOnGens func arbitrary
+transitivityOnArbitrary :: (Show a, Arbitrary a) => (a -> a -> Bool) -> Property
+transitivityOnArbitrary func = transitivityOnGens func arbitrary shrink
diff --git a/src/Test/Validity/Shrinking/Property.hs b/src/Test/Validity/Shrinking/Property.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Validity/Shrinking/Property.hs
@@ -0,0 +1,85 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-- | Tests for shrinking functions
+module Test.Validity.Shrinking.Property
+    ( shrinkPreservesValidOnGenValid
+    , shrinkPreservesInvalidOnGenInvalid
+    , shrinkValidPreservesValid
+    , shrinkInvalidPreservesInvalid
+    , shrinkingStaysValid
+    , shrinkingStaysInvalid
+    , shrinkingPreserves
+    ) where
+
+import Data.GenValidity
+
+import Test.QuickCheck
+
+-- |
+--
+-- prop> shrinkPreservesValidOnGenValid (:[])
+shrinkPreservesValidOnGenValid ::
+       forall a. (Show a, GenValid a)
+    => (a -> [a])
+    -> Property
+shrinkPreservesValidOnGenValid = shrinkingStaysValid genValid
+
+-- |
+--
+-- prop> shrinkPreservesInvalidOnGenInvalid (:[])
+shrinkPreservesInvalidOnGenInvalid ::
+       forall a. (Show a, GenInvalid a)
+    => (a -> [a])
+    -> Property
+shrinkPreservesInvalidOnGenInvalid = shrinkingStaysValid genInvalid
+
+-- |
+--
+-- prop> shrinkValidPreservesValid (pure 5)
+shrinkValidPreservesValid ::
+       forall a. (Show a, GenValid a)
+    => Gen a
+    -> Property
+shrinkValidPreservesValid gen = shrinkingStaysValid gen shrinkValid
+
+-- |
+--
+-- prop> shrinkInvalidPreservesInvalid (pure (1/0) :: Gen Double)
+shrinkInvalidPreservesInvalid ::
+       forall a. (Show a, GenInvalid a)
+    => Gen a
+    -> Property
+shrinkInvalidPreservesInvalid gen = shrinkingStaysValid gen shrinkInvalid
+
+-- |
+--
+-- prop> shrinkingStaysValid (pure 5 :: Gen Double) (\d -> [d - 1, d - 2])
+shrinkingStaysValid ::
+       forall a. (Show a, Validity a)
+    => Gen a
+    -> (a -> [a])
+    -> Property
+shrinkingStaysValid gen s = shrinkingPreserves gen s isValid
+
+-- |
+--
+-- prop> shrinkingStaysInvalid (pure (1/0) :: Gen Double) (:[])
+shrinkingStaysInvalid ::
+       forall a. (Show a, Validity a)
+    => Gen a
+    -> (a -> [a])
+    -> Property
+shrinkingStaysInvalid gen s = shrinkingPreserves gen s isInvalid
+
+-- |
+--
+-- prop> shrinkingPreserves (pure 5) (:[]) (== 5)
+shrinkingPreserves ::
+       forall a. Show a
+    => Gen a
+    -> (a -> [a])
+    -> (a -> Bool)
+    -> Property
+shrinkingPreserves gen s p = forAll gen $ \d -> not (p d) || all p (s d)
diff --git a/test/DocTest.hs b/test/DocTest.hs
--- a/test/DocTest.hs
+++ b/test/DocTest.hs
@@ -1,3 +1,8 @@
+{-# LANGUAGE CPP #-}
+#if !MIN_VERSION_base(4,8,0)
+import Data.Functor ((<$>))
+#endif
+
 import Test.DocTest
 
 import Control.Monad
@@ -13,9 +18,8 @@
 listFilesRecur :: FilePath -> IO [FilePath]
 listFilesRecur dir = do
     entries <-
-        fmap
             (map (dir </>) .
-             filter (\f -> f /= "." && f /= ".." && takeExtension f /= ".swp")) $
+             filter (\f -> f /= "." && f /= ".." && takeExtension f /= ".swp")) <$>
         getDirectoryContents dir
     dirs <- filterM doesDirectoryExist entries
     files <- filterM doesFileExist entries
