diff --git a/checkers.cabal b/checkers.cabal
--- a/checkers.cabal
+++ b/checkers.cabal
@@ -1,5 +1,5 @@
 Name:                checkers
-Version:             0.4.3
+Version:             0.4.4
 Cabal-Version:       >= 1.6
 Synopsis:            Check properties on standard classes and data structures.
 Category:            Testing
@@ -12,7 +12,7 @@
   &#169; 2008-2013 by Conal Elliott; BSD3 license.
   .
   Contributions from: Thomas Davie.
-Author:              Conal Elliott 
+Author:              Conal Elliott
 Maintainer:          conal@conal.net
 Copyright:           (c) 2008-2013 by Conal Elliott
 License:             BSD3
@@ -28,7 +28,7 @@
   hs-Source-Dirs:      src
   Extensions:
   Build-Depends:       base < 5, random, QuickCheck>=2.3 && <2.9, array >= 0.1
-  Exposed-Modules:     
+  Exposed-Modules:
                        Test.QuickCheck.Utils
                        Test.QuickCheck.Checkers
                        Test.QuickCheck.Classes
diff --git a/src/Test/QuickCheck/Checkers.hs b/src/Test/QuickCheck/Checkers.hs
--- a/src/Test/QuickCheck/Checkers.hs
+++ b/src/Test/QuickCheck/Checkers.hs
@@ -9,10 +9,10 @@
 -- Module      :  Test.QuickCheck.Checkers
 -- Copyright   :  (c) Conal Elliott 2007,2008
 -- License     :  BSD3
--- 
+--
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
--- 
+--
 -- Some QuickCheck helpers
 ----------------------------------------------------------------------
 
@@ -21,7 +21,7 @@
   -- * Misc
     Test, TestBatch, unbatch, checkBatch, quickBatch, verboseBatch
   -- , probablisticPureCheck
-  , Unop, Binop, genR, inverseL, inverse
+  , Unop, Binop, genR, involution, inverseL, inverse
   , FracT, NumT, OrdT, T
   -- * Generalized equality
   , EqProp(..), eq
@@ -91,7 +91,7 @@
      mapM_ pr tests
  where
    pr (s,p) = do putStr (padTo (width + 4) ("  "++s ++ ":"))
-                 Ex.catch (quickCheckWith args p) 
+                 Ex.catch (quickCheckWith args p)
                           (print :: Ex.SomeException -> IO ())
    width    = foldl' max 0 (map (length.fst) tests)
 
@@ -102,7 +102,7 @@
 -- | Check a batch tersely.
 quickBatch :: TestBatch -> IO ()
 quickBatch = checkBatch quick'
- 
+
 -- | Check a batch verbosely.
 verboseBatch :: TestBatch -> IO ()
 verboseBatch = checkBatch verbose'
@@ -150,11 +150,15 @@
 genR :: Random a => (a, a) -> Gen a
 genR (lo,hi) = fmap (fst . randomR (lo,hi)) rand
 
+-- | @f@ is its own inverse. See also 'inverse'.
+involution :: (Show a, Arbitrary a, EqProp a) =>
+              (a -> a) -> Property
+involution f = f `inverseL` f
 
 -- | @f@ is a left inverse of @g@.  See also 'inverse'.
 inverseL :: (EqProp b, Arbitrary b, Show b) =>
             (a -> b) -> (b -> a) -> Property
-f `inverseL` g = f . g =-= id 
+f `inverseL` g = f . g =-= id
 
 -- | @f@ is a left and right inverse of @g@.  See also 'inverseL'.
 inverse :: ( EqProp a, Arbitrary a, Show a
diff --git a/src/Test/QuickCheck/Classes.hs b/src/Test/QuickCheck/Classes.hs
--- a/src/Test/QuickCheck/Classes.hs
+++ b/src/Test/QuickCheck/Classes.hs
@@ -8,10 +8,10 @@
 -- Module      :  Test.QuickCheck.Classes
 -- Copyright   :  (c) Conal Elliott 2008
 -- License     :  BSD3
--- 
+--
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
--- 
+--
 -- Some QuickCheck properties for standard type classes
 ----------------------------------------------------------------------
 
@@ -59,7 +59,7 @@
 
 
 -- | 'Ord' morphism properties.  @h@ is an 'Ord' morphism iff:
--- 
+--
 -- >    a <= b = h a <= h b
 -- >
 -- >    h (a `min` b) = h a `min` h b
@@ -76,7 +76,7 @@
  where
    distrib  :: (forall c. Ord c => c -> c -> c) -> Property
    distrib  op = property $ \ u v -> h (u `op` v) =-= h u `op` h v
-   
+
    distrib' :: EqProp d => (forall c. Ord c => c -> c -> d) -> Property
    distrib' op = property $ \ u v -> u `op` v =-= h u `op` h v
 
@@ -143,7 +143,7 @@
     binopP :: (a->b) -> (m a) -> (m a) -> Property
     binopP f u v = (fmap f) (u `mappend` v) =-= (fmap f u) `mappend` (fmap f v)
 
--- <camio> There I have an attempt at doing this. I eventually implemented 
+-- <camio> There I have an attempt at doing this. I eventually implemented
 -- those semanticMorphisms as their own functions. I'm not too thrilled with
 -- that implementation, but it works.
 
@@ -164,15 +164,15 @@
  where
    identityP :: Property
    composeP  :: (b -> c) -> (a -> b) -> Property
-   
+
    identityP = fmap id =-= (id :: m a -> m a)
    composeP g f = fmap g . fmap f =-= (fmap (g.f) :: m a -> m c)
 
 -- Note the similarity between 'functor' and 'monoidMorphism'.  The
 -- functor laws say that 'fmap' is a homomorphism w.r.t '(.)':
--- 
+--
 --   functor = const ("functor", homomorphism endoMonoidD endoMonoidD fmap)
--- 
+--
 -- However, I don't think the types can work out, since 'fmap' is used at
 -- three different types.
 
@@ -232,7 +232,7 @@
    homomorphismP :: (a -> b) -> a -> Property
    interchangeP  :: m (a -> b) -> a -> Property
    functorP      :: (a -> b) -> m a -> Property
-   
+
    identityP v        = (pure id <*> v) =-= v
    compositionP u v w = (pure (.) <*> u <*> v <*> w) =-= (u <*> (v <*> w))
    homomorphismP f x  = (pure f <*> pure x) =-= (pure (f x) :: m b)
@@ -255,7 +255,7 @@
  where
    pureP  :: NumT -> Property
    applyP :: f (NumT->T) -> f NumT -> Property
-   
+
    pureP a = q (pure a) =-= pure a
    applyP mf mx = q (mf <*> mx) =-= (q mf <*> q mx)
 
@@ -292,7 +292,7 @@
    leftP  :: (a -> m b) -> a -> Property
    rightP :: m a -> Property
    assocP :: m a -> (a -> m b) -> (b -> m c) -> Property
-   
+
    leftP f a    = (return a >>= f)  =-= f a
    rightP m     = (m >>= return)    =-=  m
    assocP m f g = ((m >>= f) >>= g) =-= (m >>= (\x -> f x >>= g))
@@ -350,7 +350,7 @@
    returnP :: NumT -> Property
    bindP :: f NumT -> (NumT -> f T) -> Property
    joinP :: f (f (NumT->T)) -> Property
-   
+
    returnP a = q (return a) =-= return a
    bindP u k = q (u >>= k)  =-= (q u >>= q . k)
    joinP uu  = q (join uu)  =-= join (fmap q (q uu))
@@ -471,21 +471,21 @@
   where
     assocP :: a b c -> a c d -> a d e -> Property
     assocP f g h = ((f >>> g) >>> h) =-= (f >>> (g >>> h))
-    
+
     arrDistributesP :: (b -> c) -> (c -> d) -> Property
     arrDistributesP f g = ((arr (f >>> g)) :: a b d) =-= (arr f >>> arr g)
-    
+
     firstAsFunP :: (b -> c) -> Property
     firstAsFunP f = (first (arr f) :: a (b,d) (c,d)) =-= arr (first f)
 
     firstKeepCompP :: a b c -> a c d -> Property
     firstKeepCompP f g =
       ((first (f >>> g)) :: (a (b,e) (d,e))) =-= (first f >>> first g)
- 
+
     firstIsFstP :: a b c -> Property
     firstIsFstP f = ((first f :: a (b,d) (c,d)) >>> arr fst)
                       =-= (arr fst >>> f)
-    
+
     secondMovesP :: (a b c) -> (d -> e) -> Property
     secondMovesP f g = (first f >>> second (arr g))
                          =-= ((second (arr g)) >>> first f)
diff --git a/src/Test/QuickCheck/Instances.hs b/src/Test/QuickCheck/Instances.hs
--- a/src/Test/QuickCheck/Instances.hs
+++ b/src/Test/QuickCheck/Instances.hs
@@ -8,9 +8,9 @@
        ,module Test.QuickCheck.Instances.Ord
        ,module Test.QuickCheck.Instances.Tuple
        ) where
-       
+
 import Test.QuickCheck.Instances.Array ()
-import Test.QuickCheck.Instances.Char 
+import Test.QuickCheck.Instances.Char
 import Test.QuickCheck.Instances.Eq
 import Test.QuickCheck.Instances.List
 import Test.QuickCheck.Instances.Maybe
diff --git a/src/Test/QuickCheck/Instances/Array.hs b/src/Test/QuickCheck/Instances/Array.hs
--- a/src/Test/QuickCheck/Instances/Array.hs
+++ b/src/Test/QuickCheck/Instances/Array.hs
@@ -7,7 +7,7 @@
 
 instance (Ix a, Integral a, Arbitrary b) => Arbitrary (Array a b) where
   arbitrary   =
-    (\x -> listArray (0,fromIntegral (length x - 1)) x) <$> arbitrary 
+    (\x -> listArray (0,fromIntegral (length x - 1)) x) <$> arbitrary
 
 instance (Ix a, Integral a, CoArbitrary b) => CoArbitrary (Array a b) where
   coarbitrary = coarbitrary . elems
diff --git a/src/Test/QuickCheck/Instances/Num.hs b/src/Test/QuickCheck/Instances/Num.hs
--- a/src/Test/QuickCheck/Instances/Num.hs
+++ b/src/Test/QuickCheck/Instances/Num.hs
@@ -1,4 +1,4 @@
-module Test.QuickCheck.Instances.Num 
+module Test.QuickCheck.Instances.Num
        (nonNegative,nonPositive
        ,negative,positive
        ,nonZero,nonZero_
diff --git a/src/Test/QuickCheck/Later.hs b/src/Test/QuickCheck/Later.hs
--- a/src/Test/QuickCheck/Later.hs
+++ b/src/Test/QuickCheck/Later.hs
@@ -4,10 +4,10 @@
 -- Module      :  Data.Later
 -- Copyright   :  (c) David Sankel 2008
 -- License     :  BSD3
--- 
+--
 -- Maintainer  :  david@sankelsoftware.com
 -- Stability   :  experimental
--- 
+--
 -- Later. Allows for testing of functions that depend on the order of
 -- evaluation.
 --
@@ -45,7 +45,7 @@
            del t1 # del t2 =-= del t2 # del t1
 
 -- Note that we delay v by t1 and by t2 twice.
--- 
+--
 -- TODO: make sure CSE isn't kicking in.  Examine the core code.
 
 -- | Is the given function associative when restricted to the same value
@@ -75,7 +75,7 @@
 
 -- | A value that is never available.  Rerun of @hang@ from unamb, but
 -- replicated to avoid mutual dependency.
--- 
+--
 -- TODO: Remove when this module is moved into the unamb-test package.
 delayForever :: a
 delayForever = unsafePerformIO $ do _ <- forever (threadDelay maxBound)
diff --git a/src/Test/QuickCheck/Utils.hs b/src/Test/QuickCheck/Utils.hs
--- a/src/Test/QuickCheck/Utils.hs
+++ b/src/Test/QuickCheck/Utils.hs
@@ -4,7 +4,7 @@
 -- Module      :  Test.QuickCheck.Utils
 -- Copyright   :  (c) Andy Gill 2001
 -- License     :  BSD-style (see the file libraries/base/LICENSE)
--- 
+--
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
 -- Portability :  portable
@@ -26,9 +26,9 @@
 
 import Test.QuickCheck
 
-isAssociativeBy :: (Show a,Testable prop) 
+isAssociativeBy :: (Show a,Testable prop)
 		=> (a -> a -> prop) -> Gen a -> (a -> a -> a) -> Property
-isAssociativeBy (=~=) src (#) = 
+isAssociativeBy (=~=) src (#) =
      	forAll src $ \ a ->
      	forAll src $ \ b ->
      	forAll src $ \ c ->
@@ -37,7 +37,7 @@
 isAssociative :: (Arbitrary a,Show a,Eq a) => (a -> a -> a) -> Property
 isAssociative = isAssociativeBy (==) arbitrary
 
-isCommutableBy :: (Show a,Testable prop) 
+isCommutableBy :: (Show a,Testable prop)
 	       => (b -> b -> prop) -> Gen a -> (a -> a -> b) -> Property
 isCommutableBy (=~=) src (#) =
 	forAll src $ \ a ->
@@ -48,7 +48,7 @@
 isCommutable = isCommutableBy (==) arbitrary
 
 isTotalOrder :: (Arbitrary a,Show a,Ord a) => a -> a -> Property
-isTotalOrder x y = 
+isTotalOrder x y =
     classify (x > y)  "less than" $
     classify (x == y) "equals" $
     classify (x < y)  "greater than" $
