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.0
+version:             0.1.0.1
 synopsis:            Standard spec's for GenValidity instances
 description:         Please see README.md
 homepage:            https://github.com/NorfairKing/validity#readme
diff --git a/src/Data/GenValidity/Hspec.hs b/src/Data/GenValidity/Hspec.hs
--- a/src/Data/GenValidity/Hspec.hs
+++ b/src/Data/GenValidity/Hspec.hs
@@ -1,21 +1,29 @@
-{-|
-
- These are standard tests that you should add to your @hspec@ test suite
- if you implemented @GenValidity@ instances for your own data types.
-
- Use them like this:
+{-# LANGUAGE MultiParamTypeClasses #-}
+module Data.GenValidity.Hspec
+    ( module Data.GenValidity
+    -- * Tests for GenValidity instances
+    , proxy
+    , genspec
+    , arbitrarySpec
+    , validitySpec
 
- > mySpec :: Spec
- > mySpec = do
- >     genspec (proxy :: MyType)
- >     genspec (proxy :: MyOtherType)
+    -- * Standard tests involving validity
+    , producesValidsOnGen
+    , alwaysProducesValid
+    , producesValidsOnValids
+    , producesValidsOnGens2
+    , alwaysProducesValid2
+    , producesValidsOnValids2
 
- HSpec will take care of the rest.
+    -- * Standard tests involving functions that can fail
 
- -}
-module Data.GenValidity.Hspec
-    ( module Data.GenValidity
-    , module Data.GenValidity.Hspec
+    , CanFail(..)
+    , succeedsOnGen
+    , succeedsOnValidInput
+    , failsOnGen
+    , failsOnInvalidInput
+    , validIfSucceedsOnGen
+    , validIfSucceeds
     ) where
 
 import           Data.GenValidity
@@ -97,3 +105,126 @@
                 (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)
