diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+### 3.5 [2017.01.07]
+* Add `TextShow(1)` instances for `Data.Graph.SCC`
+* `TextShow.Instances` no longer reexports the entirety of `TextShow`. Doing so meant that `text-show-instances` would be burdened with bumping its major version number every time that `text-show` made an API change in `TextShow` in order to follow the PVP.
+* Remove `TextShow.GHC.PackageDb` module
+* Refactor test suite
+
 ## 3.4
 * Require `text-show-3.4` or later
 * Update testsuite to be buildable with `text-show-3.4`
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014-2016, Ryan Scott
+Copyright (c) 2014-2017, Ryan Scott
 
 All rights reserved.
 
diff --git a/src/TextShow/Compiler/Hoopl.hs b/src/TextShow/Compiler/Hoopl.hs
--- a/src/TextShow/Compiler/Hoopl.hs
+++ b/src/TextShow/Compiler/Hoopl.hs
@@ -5,7 +5,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Compiler.Hoopl
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Control/Applicative/Trans.hs b/src/TextShow/Control/Applicative/Trans.hs
--- a/src/TextShow/Control/Applicative/Trans.hs
+++ b/src/TextShow/Control/Applicative/Trans.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Control.Applicative.Trans
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Control/Monad/Trans.hs b/src/TextShow/Control/Monad/Trans.hs
--- a/src/TextShow/Control/Monad/Trans.hs
+++ b/src/TextShow/Control/Monad/Trans.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans -fno-warn-warnings-deprecations #-}
 {-|
 Module:      TextShow.Control.Monad.Trans
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Data/Bifunctor.hs b/src/TextShow/Data/Bifunctor.hs
--- a/src/TextShow/Data/Bifunctor.hs
+++ b/src/TextShow/Data/Bifunctor.hs
@@ -5,7 +5,7 @@
 
 {-|
 Module:      TextShow.Data.Bifunctor
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Data/Binary.hs b/src/TextShow/Data/Binary.hs
--- a/src/TextShow/Data/Binary.hs
+++ b/src/TextShow/Data/Binary.hs
@@ -4,7 +4,7 @@
 
 {-|
 Module:      TextShow.Data.Binary
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Data/Containers.hs b/src/TextShow/Data/Containers.hs
--- a/src/TextShow/Data/Containers.hs
+++ b/src/TextShow/Data/Containers.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Data.Containers
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,6 +17,7 @@
       liftShowbIntMapPrec
     , showbIntSetPrec
     , liftShowbMapPrec2
+    , liftShowbSCCPrec
     , liftShowbSequencePrec
     , liftShowbViewLPrec
     , liftShowbViewRPrec
@@ -25,7 +26,7 @@
     ) where
 
 import qualified Data.Foldable as F
-
+import           Data.Graph (SCC)
 import qualified Data.IntMap as IM
 import           Data.IntMap (IntMap)
 import qualified Data.IntSet as IS
@@ -70,6 +71,14 @@
                                        (const sp2) undefined) p . M.toList
 {-# INLINE liftShowbMapPrec2 #-}
 
+-- | Convert an 'SCC' to a 'Builder' with the given show functions and precedence.
+--
+-- /Since: next/
+liftShowbSCCPrec :: (Int -> vertex -> Builder) -> ([vertex] -> Builder)
+                 -> Int -> SCC vertex -> Builder
+liftShowbSCCPrec = liftShowbPrec
+{-# INLINE liftShowbSCCPrec #-}
+
 -- | Convert a 'Sequence' to a 'Builder' with the given show function and precedence.
 --
 -- /Since: 3/
@@ -154,5 +163,7 @@
     liftShowbPrec _ = liftShowbSetPrec
     INLINE_INST_FUN(liftShowbPrec)
 
+$(deriveTextShow  ''SCC)
+$(deriveTextShow1 ''SCC)
 $(deriveTextShow  ''Tree)
 $(deriveTextShow1 ''Tree)
diff --git a/src/TextShow/Data/Functor/Trans.hs b/src/TextShow/Data/Functor/Trans.hs
--- a/src/TextShow/Data/Functor/Trans.hs
+++ b/src/TextShow/Data/Functor/Trans.hs
@@ -8,7 +8,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Data.Functor.Trans
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Data/Tagged.hs b/src/TextShow/Data/Tagged.hs
--- a/src/TextShow/Data/Tagged.hs
+++ b/src/TextShow/Data/Tagged.hs
@@ -8,7 +8,7 @@
 {-# OPTIONS -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Data.Tagged
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Data/Time.hs b/src/TextShow/Data/Time.hs
--- a/src/TextShow/Data/Time.hs
+++ b/src/TextShow/Data/Time.hs
@@ -6,7 +6,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Data.Time
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Data/UnorderedContainers.hs b/src/TextShow/Data/UnorderedContainers.hs
--- a/src/TextShow/Data/UnorderedContainers.hs
+++ b/src/TextShow/Data/UnorderedContainers.hs
@@ -2,7 +2,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Data.UnorderedContainers
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Data/Vector.hs b/src/TextShow/Data/Vector.hs
--- a/src/TextShow/Data/Vector.hs
+++ b/src/TextShow/Data/Vector.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Data.Vector
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/GHC/LanguageExtensions/Type.hs b/src/TextShow/GHC/LanguageExtensions/Type.hs
--- a/src/TextShow/GHC/LanguageExtensions/Type.hs
+++ b/src/TextShow/GHC/LanguageExtensions/Type.hs
@@ -1,25 +1,25 @@
 {-# LANGUAGE CPP             #-}
 
-#if defined(MIN_VERSION_ghc_boot)
+#if defined(MIN_VERSION_ghc_boot_th)
 {-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 #endif
 
 {-|
 Module:      TextShow.GHC.LanguageExtensions.Type
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
 Portability: GHC
 
 Monomorphic 'TextShow' function for the 'Extension' data type.
-This module only exports functions if using @ghc-boot@.
+This module only exports functions if using @ghc-boot-th@.
 
 /Since: 3.3/
 -}
 module TextShow.GHC.LanguageExtensions.Type (
-#if !defined(MIN_VERSION_ghc_boot)
+#if !defined(MIN_VERSION_ghc_boot_th)
     ) where
 #else
       showbExtension
diff --git a/src/TextShow/GHC/PackageDb.hs b/src/TextShow/GHC/PackageDb.hs
deleted file mode 100644
--- a/src/TextShow/GHC/PackageDb.hs
+++ /dev/null
@@ -1,109 +0,0 @@
-{-# LANGUAGE CPP             #-}
-
-#if defined(MIN_VERSION_ghc_boot)
-{-# LANGUAGE TemplateHaskell #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-#endif
-
-{-|
-Module:      TextShow.GHC.PackageDb
-Copyright:   (C) 2014-2016 Ryan Scott
-License:     BSD-style (see the file LICENSE)
-Maintainer:  Ryan Scott
-Stability:   Provisional
-Portability: GHC
-
-Monomorphic 'TextShow' functions for data types in the "GHC.PackageDb" module.
-This module only exports functions if using @ghc-boot@.
-
-/Since: 3.3/
--}
-module TextShow.GHC.PackageDb (
-#if !defined(MIN_VERSION_ghc_boot)
-    ) where
-#else
-      liftShowbInstalledPackageInfoPrec2
-# if __GLASGOW_HASKELL__ >= 801
-    , liftShowbDbModulePrec2
-# else
-    , liftShowbOriginalModulePrec2
-    , liftShowbExposedModulePrec2
-# endif
-    ) where
-
-import GHC.PackageDb
-
-import TextShow (TextShow(..), TextShow2(..), Builder)
-import TextShow.TH (deriveTextShow, deriveTextShow1, deriveTextShow2)
-
--- | Convert an 'InstalledPackageInfo' value to a 'Builder' with the given
--- show functions and precedence.
--- This function is only available when using @ghc-boot@ and GHC 8.1 or later.
---
--- /Since: 3.3/
-liftShowbInstalledPackageInfoPrec2 :: ( TextShow srcpkgid
-                                      , TextShow srcpkgname
-# if __GLASGOW_HASKELL__ >= 801
-                                      , TextShow unitid
-# endif
-                                      )
-                                   => (Int -> a -> Builder) -> ([a] -> Builder)
-                                   -> (Int -> b -> Builder) -> ([b] -> Builder)
-                                   -> Int
-                                   -> InstalledPackageInfo srcpkgid srcpkgname
-# if __GLASGOW_HASKELL__ >= 801
-                                                           unitid
-# endif
-                                                           a b
-                                   -> Builder
-liftShowbInstalledPackageInfoPrec2 = liftShowbPrec2
-
-# if __GLASGOW_HASKELL__ >= 801
--- | Convert a 'DbModule' value to a 'Builder' with the given show functions
--- and precedence.
--- This function is only available when using @ghc-boot@.
---
--- /Since: 3.3/
-liftShowbDbModulePrec2 :: (Int -> unitid     -> Builder) -> ([unitid]     -> Builder)
-                       -> (Int -> modulename -> Builder) -> ([modulename] -> Builder)
-                       -> Int -> DbModule unitid modulename -> Builder
-liftShowbDbModulePrec2 = liftShowbPrec2
-# else
--- | Convert an 'OriginalModule' value to a 'Builder' with the given show functions
--- and precedence.
--- This function is only available when using @ghc-boot@.
---
--- /Since: 3.3/
-liftShowbOriginalModulePrec2 :: (Int -> unitid     -> Builder) -> ([unitid]     -> Builder)
-                             -> (Int -> modulename -> Builder) -> ([modulename] -> Builder)
-                             -> Int -> OriginalModule unitid modulename -> Builder
-liftShowbOriginalModulePrec2 = liftShowbPrec2
-
--- | Convert an 'ExposedModule' value to a 'Builder' with the given show functions
--- and precedence.
--- This function is only available when using @ghc-boot@.
---
--- /Since: 3.3/
-liftShowbExposedModulePrec2 :: (Int -> unitid     -> Builder) -> ([unitid]     -> Builder)
-                            -> (Int -> modulename -> Builder) -> ([modulename] -> Builder)
-                            -> Int -> ExposedModule unitid modulename -> Builder
-liftShowbExposedModulePrec2 = liftShowbPrec2
-# endif
-
-$(deriveTextShow  ''InstalledPackageInfo)
-$(deriveTextShow1 ''InstalledPackageInfo)
-$(deriveTextShow2 ''InstalledPackageInfo)
-# if __GLASGOW_HASKELL__ >= 801
-$(deriveTextShow  ''DbModule)
-$(deriveTextShow1 ''DbModule)
-$(deriveTextShow2 ''DbModule)
-# else
-$(deriveTextShow  ''OriginalModule)
-$(deriveTextShow1 ''OriginalModule)
-$(deriveTextShow2 ''OriginalModule)
-
-$(deriveTextShow  ''ExposedModule)
-$(deriveTextShow1 ''ExposedModule)
-$(deriveTextShow2 ''ExposedModule)
-# endif
-#endif
diff --git a/src/TextShow/Instances.hs b/src/TextShow/Instances.hs
--- a/src/TextShow/Instances.hs
+++ b/src/TextShow/Instances.hs
@@ -6,7 +6,7 @@
 
 {-|
 Module:      TextShow.Instances
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -22,11 +22,9 @@
       TextShow(..)
     , TextShow1(..)
     , TextShow2(..)
-    -- * Module re-export
-    , module TextShow
     ) where
 
-import TextShow
+import TextShow (TextShow(..), TextShow1(..), TextShow2(..))
 
 import TextShow.Compiler.Hoopl              ()
 
@@ -43,7 +41,6 @@
 import TextShow.Data.Vector                 ()
 
 import TextShow.GHC.LanguageExtensions.Type ()
-import TextShow.GHC.PackageDb               ()
 
 import TextShow.Language.Haskell.TH         ()
 
@@ -55,6 +52,6 @@
 import TextShow.System.Time                 ()
 import TextShow.System.Win32                ()
 
-import TextShow.Text.PrettyPrint          ()
+import TextShow.Text.PrettyPrint            ()
 
-import TextShow.Trace.Hpc                 ()
+import TextShow.Trace.Hpc                   ()
diff --git a/src/TextShow/Language/Haskell/TH.hs b/src/TextShow/Language/Haskell/TH.hs
--- a/src/TextShow/Language/Haskell/TH.hs
+++ b/src/TextShow/Language/Haskell/TH.hs
@@ -6,7 +6,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Language.Haskell.TH
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -35,6 +35,10 @@
     , showbDecidedStrictness
 #endif
     , showbDecPrec
+#if MIN_VERSION_template_haskell(2,12,0)
+    , showbDerivClausePrec
+    , showbDerivStrategy
+#endif
     , showbExpPrec
     , showbFamFlavour
 #if MIN_VERSION_template_haskell(2,11,0)
@@ -72,7 +76,7 @@
     , showbOverlap
 #endif
     , showbPatPrec
-#if __GLASGOW_HASKELL__ >= 801
+#if MIN_VERSION_template_haskell(2,12,0)
     , showbPatSynArgsPrec
     , showbPatSynDirPrec
 #endif
@@ -553,16 +557,30 @@
 showbTypeFamilyHeadPrec = showbPrec
 #endif
 
-#if __GLASGOW_HASKELL__ >= 801
+#if MIN_VERSION_template_haskell(2,12,0)
+-- | Convert a 'DerivClause' value to a 'Builder' with the given precedence.
+-- This function is only available with @template-haskell-2.12.0.0@ or later.
+--
+-- /Since: next/
+showbDerivClausePrec :: Int -> DerivClause -> Builder
+showbDerivClausePrec = showbPrec
+
+-- | Convert a 'DerivStrategy' to a 'Builder'.
+-- This function is only available with @template-haskell-2.12.0.0@ or later.
+--
+-- /Since: next/
+showbDerivStrategy :: DerivStrategy -> Builder
+showbDerivStrategy = showb
+
 -- | Convert a 'PatSynArgs' value to a 'Builder' with the given precedence.
--- This function is only available with GHC 8.1 or later.
+-- This function is only available with @template-haskell-2.12.0.0@ or later.
 --
 -- /Since: 3.3/
 showbPatSynArgsPrec :: Int -> PatSynArgs -> Builder
 showbPatSynArgsPrec = showbPrec
 
 -- | Convert a 'PatSynDir' value to a 'Builder' with the given precedence.
--- This function is only available with GHC 8.1 or later.
+-- This function is only available with @template-haskell-2.12.0.0@ or later.
 --
 -- /Since: 3.3/
 showbPatSynDirPrec :: Int -> PatSynDir -> Builder
@@ -646,7 +664,9 @@
 $(deriveTextShow ''Strict)
 #endif
 
-#if __GLASGOW_HASKELL__ >= 801
+#if MIN_VERSION_template_haskell(2,12,0)
+$(deriveTextShow ''DerivClause)
+$(deriveTextShow ''DerivStrategy)
 $(deriveTextShow ''PatSynArgs)
 $(deriveTextShow ''PatSynDir)
 #endif
diff --git a/src/TextShow/System/Console/Haskeline.hs b/src/TextShow/System/Console/Haskeline.hs
--- a/src/TextShow/System/Console/Haskeline.hs
+++ b/src/TextShow/System/Console/Haskeline.hs
@@ -4,7 +4,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.System.Console.Haskeline
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/System/Console/Terminfo.hs b/src/TextShow/System/Console/Terminfo.hs
--- a/src/TextShow/System/Console/Terminfo.hs
+++ b/src/TextShow/System/Console/Terminfo.hs
@@ -7,7 +7,7 @@
 
 {-|
 Module:      TextShow.System.Console.Terminfo
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/System/Directory.hs b/src/TextShow/System/Directory.hs
--- a/src/TextShow/System/Directory.hs
+++ b/src/TextShow/System/Directory.hs
@@ -2,7 +2,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.System.Directory
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/System/Locale.hs b/src/TextShow/System/Locale.hs
--- a/src/TextShow/System/Locale.hs
+++ b/src/TextShow/System/Locale.hs
@@ -2,7 +2,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.System.Locale
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/System/Posix.hs b/src/TextShow/System/Posix.hs
--- a/src/TextShow/System/Posix.hs
+++ b/src/TextShow/System/Posix.hs
@@ -7,7 +7,7 @@
 
 {-|
 Module:      TextShow.System.Posix
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/System/Random.hs b/src/TextShow/System/Random.hs
--- a/src/TextShow/System/Random.hs
+++ b/src/TextShow/System/Random.hs
@@ -2,7 +2,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.System.Random
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/System/Time.hs b/src/TextShow/System/Time.hs
--- a/src/TextShow/System/Time.hs
+++ b/src/TextShow/System/Time.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.System.Time
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/System/Win32.hs b/src/TextShow/System/Win32.hs
--- a/src/TextShow/System/Win32.hs
+++ b/src/TextShow/System/Win32.hs
@@ -7,7 +7,7 @@
 
 {-|
 Module:      TextShow.System.Win32
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Text/PrettyPrint.hs b/src/TextShow/Text/PrettyPrint.hs
--- a/src/TextShow/Text/PrettyPrint.hs
+++ b/src/TextShow/Text/PrettyPrint.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Text.PrettyPrint
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Text/XHtml.hs b/src/TextShow/Text/XHtml.hs
--- a/src/TextShow/Text/XHtml.hs
+++ b/src/TextShow/Text/XHtml.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Text.XHtml
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Trace/Hpc.hs b/src/TextShow/Trace/Hpc.hs
--- a/src/TextShow/Trace/Hpc.hs
+++ b/src/TextShow/Trace/Hpc.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      TextShow.Trace.Hpc
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/src/TextShow/Utils.hs b/src/TextShow/Utils.hs
--- a/src/TextShow/Utils.hs
+++ b/src/TextShow/Utils.hs
@@ -2,7 +2,7 @@
 
 {-|
 Module:      TextShow.Utils
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/tests/Instances/Compiler/Hoopl.hs b/tests/Instances/Compiler/Hoopl.hs
--- a/tests/Instances/Compiler/Hoopl.hs
+++ b/tests/Instances/Compiler/Hoopl.hs
@@ -5,7 +5,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Compiler.Hoopl
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/tests/Instances/Control/Applicative/Trans.hs b/tests/Instances/Control/Applicative/Trans.hs
--- a/tests/Instances/Control/Applicative/Trans.hs
+++ b/tests/Instances/Control/Applicative/Trans.hs
@@ -1,10 +1,18 @@
+{-# LANGUAGE CPP                        #-}
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE TypeFamilies               #-}
+
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric              #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Control.Applicative.Trans
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -14,15 +22,26 @@
 -}
 module Instances.Control.Applicative.Trans () where
 
-import Control.Applicative.Backwards (Backwards(..))
-import Control.Applicative.Lift      (Lift(..))
+import           Control.Applicative.Backwards (Backwards(..))
+import           Control.Applicative.Lift      (Lift(..))
 
-import Prelude ()
-import Prelude.Compat
+#if __GLASGOW_HASKELL__ >= 706
+import           GHC.Generics (Generic)
+#else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+#endif
 
-import Test.QuickCheck (Arbitrary(..), oneof)
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
+import           Test.QuickCheck (Arbitrary(..))
+
 deriving instance Arbitrary (f a) => Arbitrary (Backwards f a)
 
 instance (Arbitrary a, Arbitrary (f a)) => Arbitrary (Lift f a) where
-    arbitrary = oneof [Pure <$> arbitrary, Other <$> arbitrary]
+    arbitrary = genericArbitrary
+
+#if __GLASGOW_HASKELL__ >= 706
+deriving instance Generic (Lift f a)
+#else
+$(Generics.deriveAll0 ''Lift)
+#endif
diff --git a/tests/Instances/Control/Monad/Trans.hs b/tests/Instances/Control/Monad/Trans.hs
--- a/tests/Instances/Control/Monad/Trans.hs
+++ b/tests/Instances/Control/Monad/Trans.hs
@@ -6,7 +6,7 @@
 {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
 {-|
 Module:      Instances.Control.Monad.Trans
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/tests/Instances/Data/Bifunctor.hs b/tests/Instances/Data/Bifunctor.hs
--- a/tests/Instances/Data/Bifunctor.hs
+++ b/tests/Instances/Data/Bifunctor.hs
@@ -1,12 +1,15 @@
+{-# LANGUAGE CPP                        #-}
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE TypeFamilies               #-}
 {-# LANGUAGE UndecidableInstances       #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 {-|
 Module:      Instances.Data.Bifunctor
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -16,21 +19,25 @@
 -}
 module Instances.Data.Bifunctor () where
 
-import Data.Bifunctor.Biff (Biff(..))
-import Data.Bifunctor.Clown (Clown(..))
-import Data.Bifunctor.Fix (Fix(..))
-import Data.Bifunctor.Flip (Flip(..))
-import Data.Bifunctor.Join (Join(..))
-import Data.Bifunctor.Joker (Joker(..))
-import Data.Bifunctor.Product (Product(..))
-import Data.Bifunctor.Tannen (Tannen(..))
-import Data.Bifunctor.Wrapped (WrappedBifunctor(..))
+import           Data.Bifunctor.Biff (Biff(..))
+import           Data.Bifunctor.Clown (Clown(..))
+import           Data.Bifunctor.Fix (Fix(..))
+import           Data.Bifunctor.Flip (Flip(..))
+import           Data.Bifunctor.Join (Join(..))
+import           Data.Bifunctor.Joker (Joker(..))
+import           Data.Bifunctor.Product (Product(..))
+import           Data.Bifunctor.Sum (Sum(..))
+import           Data.Bifunctor.Tannen (Tannen(..))
+import           Data.Bifunctor.Wrapped (WrappedBifunctor(..))
 
-import Prelude ()
-import Prelude.Compat
+#if __GLASGOW_HASKELL__ < 702
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+#endif
 
-import Test.QuickCheck (Arbitrary(..))
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
+import           Test.QuickCheck (Arbitrary(..))
+
 deriving instance Arbitrary (p (f a) (g b)) => Arbitrary (Biff p f g a b)
 deriving instance Arbitrary (f a)           => Arbitrary (Clown f a b)
 deriving instance Arbitrary (p (Fix p a) a) => Arbitrary (Fix p a)
@@ -41,4 +48,12 @@
 deriving instance Arbitrary (p a b)         => Arbitrary (WrappedBifunctor p a b)
 
 instance (Arbitrary (f a b), Arbitrary (g a b)) => Arbitrary (Product f g a b) where
-    arbitrary = Pair <$> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
+
+instance (Arbitrary (p a b), Arbitrary (q a b)) => Arbitrary (Sum p q a b) where
+    arbitrary = genericArbitrary
+
+#if __GLASGOW_HASKELL__ < 702
+$(Generics.deriveAll0 ''Product)
+$(Generics.deriveAll0 ''Sum)
+#endif
diff --git a/tests/Instances/Data/Binary.hs b/tests/Instances/Data/Binary.hs
--- a/tests/Instances/Data/Binary.hs
+++ b/tests/Instances/Data/Binary.hs
@@ -1,7 +1,16 @@
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric      #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Data.Binary
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -11,17 +20,24 @@
 -}
 module Instances.Data.Binary () where
 
-import Data.Binary.Get.Internal (Decoder(..))
+import           Data.Binary.Get.Internal (Decoder(..))
 
-import Prelude ()
-import Prelude.Compat
+#if __GLASGOW_HASKELL__ >= 706
+import           GHC.Generics (Generic)
+#else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+#endif
 
-import Test.QuickCheck (Arbitrary(..), oneof)
-import Test.QuickCheck.Instances ()
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
+import           Test.QuickCheck (Arbitrary(..))
+import           Test.QuickCheck.Instances ()
+
 instance Arbitrary a => Arbitrary (Decoder a) where
-    arbitrary = oneof [ Fail      <$> arbitrary <*> arbitrary
-                      , Partial   <$> arbitrary
-                      , Done      <$> arbitrary <*> arbitrary
-                      , BytesRead <$> arbitrary <*> arbitrary
-                      ]
+    arbitrary = genericArbitrary
+
+#if __GLASGOW_HASKELL__ >= 706
+deriving instance Generic (Decoder a)
+#else
+$(Generics.deriveAll0 ''Decoder)
+#endif
diff --git a/tests/Instances/Data/Containers.hs b/tests/Instances/Data/Containers.hs
--- a/tests/Instances/Data/Containers.hs
+++ b/tests/Instances/Data/Containers.hs
@@ -1,7 +1,16 @@
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric      #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Data.Containers
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -11,16 +20,47 @@
 -}
 module Instances.Data.Containers () where
 
-import Data.Sequence (ViewL(..), ViewR(..))
+import           Data.Graph (SCC(..))
+import           Data.Sequence (ViewL(..), ViewR(..))
 
-import Prelude ()
-import Prelude.Compat
+#if !(MIN_VERSION_containers(0,5,9))
+# if __GLASGOW_HASKELL__ >= 706
+import           GHC.Generics (Generic)
+# else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+# endif
+#endif
 
-import Test.QuickCheck (Arbitrary(..), oneof)
-import Test.QuickCheck.Instances ()
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
+import           Test.QuickCheck (Arbitrary(..))
+import           Test.QuickCheck.Instances ()
+
+instance Arbitrary vertex => Arbitrary (SCC vertex) where
+    arbitrary = genericArbitrary
+
 instance Arbitrary a => Arbitrary (ViewL a) where
-    arbitrary = oneof [pure EmptyL, (:<) <$> arbitrary <*> arbitrary]
+    arbitrary = genericArbitrary
 
 instance Arbitrary a => Arbitrary (ViewR a) where
-    arbitrary = oneof [pure EmptyR, (:>) <$> arbitrary <*> arbitrary]
+    arbitrary = genericArbitrary
+
+#if !(MIN_VERSION_containers(0,5,8))
+# if __GLASGOW_HASKELL__ >= 706
+deriving instance Generic (ViewL a)
+deriving instance Generic (ViewR a)
+# else
+$(Generics.deriveAll0 ''ViewL)
+$(Generics.deriveAll0 ''ViewR)
+# endif
+#endif
+
+#if !(MIN_VERSION_containers(0,5,9))
+deriving instance Show vertex => Show (SCC vertex)
+
+# if __GLASGOW_HASKELL__ >= 706
+deriving instance Generic (SCC vertex)
+# else
+$(Generics.deriveAll0 ''SCC)
+# endif
+#endif
diff --git a/tests/Instances/Data/Functor/Trans.hs b/tests/Instances/Data/Functor/Trans.hs
--- a/tests/Instances/Data/Functor/Trans.hs
+++ b/tests/Instances/Data/Functor/Trans.hs
@@ -1,11 +1,10 @@
-{-# LANGUAGE CPP                        #-}
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE StandaloneDeriving         #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Data.Functor.Trans
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -16,9 +15,6 @@
 module Instances.Data.Functor.Trans () where
 
 import Data.Functor.Compose  (Compose(..))
-#if !(MIN_VERSION_QuickCheck(2,9,0))
-import Data.Functor.Constant (Constant(..))
-#endif
 import Data.Functor.Product  (Product(..))
 import Data.Functor.Reverse  (Reverse(..))
 import Data.Functor.Sum      (Sum(..))
@@ -29,9 +25,6 @@
 import Test.QuickCheck (Arbitrary(..), oneof)
 
 deriving instance Arbitrary (f (g a)) => Arbitrary (Compose f g a)
-#if !(MIN_VERSION_QuickCheck(2,9,0))
-deriving instance Arbitrary a         => Arbitrary (Constant a b)
-#endif
 deriving instance Arbitrary (f a)     => Arbitrary (Reverse f a)
 
 instance (Arbitrary (f a), Arbitrary (g a)) => Arbitrary (Product f g a) where
diff --git a/tests/Instances/Data/Tagged.hs b/tests/Instances/Data/Tagged.hs
--- a/tests/Instances/Data/Tagged.hs
+++ b/tests/Instances/Data/Tagged.hs
@@ -3,7 +3,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Data.Tagged
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/tests/Instances/GHC/LanguageExtensions/Type.hs b/tests/Instances/GHC/LanguageExtensions/Type.hs
--- a/tests/Instances/GHC/LanguageExtensions/Type.hs
+++ b/tests/Instances/GHC/LanguageExtensions/Type.hs
@@ -1,13 +1,13 @@
 {-# LANGUAGE CPP                #-}
 
-#if defined(MIN_VERSION_ghc_boot)
+#if defined(MIN_VERSION_ghc_boot_th)
 {-# LANGUAGE StandaloneDeriving #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 #endif
 
 {-|
 Module:      Instances.GHC.LanguageExtensions.Type
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,7 +17,7 @@
 -}
 module Instances.GHC.LanguageExtensions.Type () where
 
-#if defined(MIN_VERSION_ghc_boot)
+#if defined(MIN_VERSION_ghc_boot_th)
 import GHC.LanguageExtensions.Type (Extension(..))
 import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum)
 
diff --git a/tests/Instances/GHC/PackageDb.hs b/tests/Instances/GHC/PackageDb.hs
deleted file mode 100644
--- a/tests/Instances/GHC/PackageDb.hs
+++ /dev/null
@@ -1,62 +0,0 @@
-{-# LANGUAGE CPP                #-}
-
-#if defined(MIN_VERSION_ghc_boot)
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-#endif
-
-{-|
-Module:      Instances.GHC.PackageDb
-Copyright:   (C) 2014-2016 Ryan Scott
-License:     BSD-style (see the file LICENSE)
-Maintainer:  Ryan Scott
-Stability:   Provisional
-Portability: GHC
-
-Provides 'Arbitrary' instances for data types in the "GHC.PackageDb" module.
--}
-module Instances.GHC.PackageDb () where
-
-#if defined(MIN_VERSION_ghc_boot)
-import GHC.PackageDb
-
-import Instances.Miscellaneous ()
-import Instances.Utils ((<@>))
-
-import Test.QuickCheck (Arbitrary(..))
-
-instance ( Arbitrary srcpkgid
-         , Arbitrary srcpkgname
-         , Arbitrary unitid
-         , Arbitrary modulename
-# if __GLASGOW_HASKELL__ >= 801
-         , Arbitrary mod
-# endif
-         )
-  => Arbitrary ( InstalledPackageInfo srcpkgid srcpkgname unitid modulename
-# if __GLASGOW_HASKELL__ >= 801
-                 mod
-# endif
-               ) where
-    arbitrary = InstalledPackageInfo <$> arbitrary <*> arbitrary <*> arbitrary
-                                     <*> arbitrary <*> arbitrary <@> []
-                                     <*> arbitrary <@> []        <@> []
-                                     <@> []        <@> []        <@> []
-                                     <@> []        <@> []        <@> []
-                                     <@> []        <@> []        <@> []
-                                     <@> []        <*> arbitrary <*> arbitrary
-                                     <*> arbitrary <*> arbitrary
-
-# if __GLASGOW_HASKELL__ >= 801
-instance (Arbitrary unitid, Arbitrary modulename)
-  => Arbitrary (DbModule unitid modulename) where
-    arbitrary = DbModule <$> arbitrary <*> arbitrary
-# else
-instance (Arbitrary unitid, Arbitrary modulename)
-  => Arbitrary (ExposedModule unitid modulename) where
-    arbitrary = ExposedModule <$> arbitrary <*> arbitrary
-
-instance (Arbitrary unitid, Arbitrary modulename)
-  => Arbitrary (OriginalModule unitid modulename) where
-    arbitrary = OriginalModule <$> arbitrary <*> arbitrary
-# endif
-#endif
diff --git a/tests/Instances/Language/Haskell/TH.hs b/tests/Instances/Language/Haskell/TH.hs
--- a/tests/Instances/Language/Haskell/TH.hs
+++ b/tests/Instances/Language/Haskell/TH.hs
@@ -7,7 +7,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Language.Haskell.TH
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,12 +17,10 @@
 -}
 module Instances.Language.Haskell.TH () where
 
-#if !(MIN_VERSION_template_haskell(2,10,0))
-import GHC.Exts (Int(I#))
-#endif
-
 import Instances.Utils ((<@>))
+import Instances.Utils.GenericArbitrary (genericArbitrary)
 
+import Language.Haskell.TH.Instances ()
 import Language.Haskell.TH.PprLib (Doc, text)
 import Language.Haskell.TH.Syntax
 #if !(MIN_VERSION_template_haskell(2,8,0))
@@ -125,7 +123,11 @@
         , TySynInstD <$> arbitrary <*> arbitrary <*> arbitrary
 #endif
 #if MIN_VERSION_template_haskell(2,10,0)
-        , StandaloneDerivD <$> arbitrary <*> arbitrary
+        , StandaloneDerivD <$> arbitrary
+                           <*> arbitrary
+# if MIN_VERSION_template_haskell(2,12,0)
+                           <*> arbitrary
+# endif
         , DefaultSigD <$> arbitrary <*> arbitrary
 #endif
 #if MIN_VERSION_template_haskell(2,11,0)
@@ -134,7 +136,7 @@
 #else
         , FamilyD <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
 #endif
-#if __GLASGOW_HASKELL__ >= 801
+#if MIN_VERSION_template_haskell(2,12,0)
         , PatSynD <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
         , PatSynSigD <$> arbitrary <*> arbitrary
 #endif
@@ -249,7 +251,7 @@
     arbitrary = arbitraryBoundedEnum
 
 instance Arbitrary Fixity where
-    arbitrary = Fixity <$> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 deriving instance Bounded FixityDirection
 deriving instance Enum FixityDirection
@@ -257,13 +259,10 @@
     arbitrary = arbitraryBoundedEnum
 
 instance Arbitrary Foreign where
-    arbitrary = oneof [ ImportF <$> arbitrary <*> arbitrary <*> arbitrary
-                                <*> arbitrary <*> arbitrary
-                      , ExportF <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary FunDep where
-    arbitrary = FunDep <$> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary Guard where
         arbitrary = oneof $ map pure [ NormalG fExp
@@ -304,7 +303,7 @@
 #if MIN_VERSION_template_haskell(2,7,0)
         , pure $ FamilyI fDec [fDec]
 #endif
-#if __GLASGOW_HASKELL__ >= 801
+#if MIN_VERSION_template_haskell(2,12,0)
         , PatSynI    <$> arbitrary <*> arbitrary
 #endif
         ]
@@ -326,45 +325,20 @@
 --         ]
 
 instance Arbitrary Lit where
-    arbitrary = oneof [ CharL       <$> arbitrary
-                      , StringL     <$> arbitrary
-                      , IntegerL    <$> arbitrary
-                      , RationalL   <$> arbitrary
-                      , IntPrimL    <$> arbitrary
-                      , WordPrimL   <$> arbitrary
-                      , FloatPrimL  <$> arbitrary
-                      , DoublePrimL <$> arbitrary
-#if MIN_VERSION_template_haskell(2,5,0)
-                      , StringPrimL <$> arbitrary
-#endif
-#if MIN_VERSION_template_haskell(2,11,0)
-                      , CharPrimL   <$> arbitrary
-#endif
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary Loc where
-    arbitrary = Loc <$> arbitrary <*> arbitrary <*> arbitrary
-                    <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary Match where
     arbitrary = Match <$> arbitrary <@> fBody <@> [fDec]
 --     arbitrary = Match <$> arbitrary <*> arbitrary <*> arbitrary
 
 instance Arbitrary Name where
-    arbitrary = Name <$> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary NameFlavour where
-    arbitrary = oneof [ pure NameS
-                      , NameQ <$> arbitrary
-#if MIN_VERSION_template_haskell(2,10,0)
-                      , NameU <$> arbitrary
-                      , NameL <$> arbitrary
-#else
-                      , (\(I# i#) -> NameU i#) <$> arbitrary
-                      , (\(I# i#) -> NameL i#) <$> arbitrary
-#endif
-                      , NameG <$> arbitrary <*> arbitrary <*> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
 deriving instance Bounded NameIs
 deriving instance Enum NameIs
@@ -426,25 +400,7 @@
 --                       ]
 
 instance Arbitrary Pragma where
-    arbitrary = oneof
-        [
-#if MIN_VERSION_template_haskell(2,8,0)
-          InlineP         <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-        , SpecialiseP     <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-        , SpecialiseInstP <$> arbitrary
-        , RuleP           <$> arbitrary <*> arbitrary <*> arbitrary
-                          <*> arbitrary <*> arbitrary
-# if MIN_VERSION_template_haskell(2,9,0)
-        , AnnP            <$> arbitrary <*> arbitrary
-# endif
-# if MIN_VERSION_template_haskell(2,10,0)
-        , LineP           <$> arbitrary <*> arbitrary
-# endif
-#else
-          InlineP     <$> arbitrary <*> arbitrary
-        , SpecialiseP <$> arbitrary <*> arbitrary <*> arbitrary
-#endif
-        ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary Range where
     arbitrary = oneof $ map pure [ FromR       fExp
@@ -537,8 +493,7 @@
 
 #if MIN_VERSION_template_haskell(2,5,0) && !(MIN_VERSION_template_haskell(2,7,0))
 instance Arbitrary ClassInstance where
-    arbitrary = ClassInstance <$> arbitrary <*> arbitrary <*> arbitrary
-                              <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 #endif
 
 #if MIN_VERSION_template_haskell(2,8,0)
@@ -548,13 +503,10 @@
     arbitrary = arbitraryBoundedEnum
 
 instance Arbitrary Phases where
-    arbitrary = oneof [ pure AllPhases
-                      , FromPhase   <$> arbitrary
-                      , BeforePhase <$> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary RuleBndr where
-    arbitrary = oneof [RuleVar <$> arbitrary, TypedRuleVar <$> arbitrary <*> arbitrary]
+    arbitrary = genericArbitrary
 
 deriving instance Bounded RuleMatch
 deriving instance Enum RuleMatch
@@ -562,10 +514,10 @@
     arbitrary = arbitraryBoundedEnum
 
 instance Arbitrary TyLit where
-    arbitrary = oneof [NumTyLit <$> arbitrary, StrTyLit <$> arbitrary]
+    arbitrary = genericArbitrary
 #else
 instance Arbitrary InlineSpec where
-    arbitrary = InlineSpec <$> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary Kind where
     arbitrary = oneof [pure StarK, pure $ ArrowK fKind fKind]
@@ -574,19 +526,16 @@
 
 #if MIN_VERSION_template_haskell(2,9,0)
 instance Arbitrary AnnLookup where
-    arbitrary = oneof [AnnLookupModule <$> arbitrary, AnnLookupName <$> arbitrary]
+    arbitrary = genericArbitrary
 
 instance Arbitrary AnnTarget where
-    arbitrary = oneof [ pure ModuleAnnotation
-                      , TypeAnnotation  <$> arbitrary
-                      , ValueAnnotation <$> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary Module where
-    arbitrary = Module <$> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary ModuleInfo where
-    arbitrary = ModuleInfo <$> arbitrary
+    arbitrary = genericArbitrary
 
 deriving instance Bounded Role
 deriving instance Enum Role
@@ -594,7 +543,7 @@
     arbitrary = arbitraryBoundedEnum
 
 instance Arbitrary TySynEqn where
-    arbitrary = TySynEqn <$> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 #endif
 
 instance Arbitrary Doc where
@@ -612,7 +561,7 @@
 
 #if MIN_VERSION_template_haskell(2,11,0)
 instance Arbitrary Bang where
-    arbitrary = Bang <$> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 deriving instance Bounded DecidedStrictness
 deriving instance Enum DecidedStrictness
@@ -655,7 +604,15 @@
     arbitrary = arbitraryBoundedEnum
 #endif
 
-#if __GLASGOW_HASKELL__ >= 801
+#if MIN_VERSION_template_haskell(2,12,0)
+instance Arbitrary DerivClause where
+    arbitrary = genericArbitrary
+
+deriving instance Bounded DerivStrategy
+deriving instance Enum DerivStrategy
+instance Arbitrary DerivStrategy where
+    arbitrary = arbitraryBoundedEnum
+
 instance Arbitrary PatSynArgs where
     arbitrary = oneof $ map pure [ PrefixPatSyn [fName]
                                  , InfixPatSyn fName fName
diff --git a/tests/Instances/Miscellaneous.hs b/tests/Instances/Miscellaneous.hs
--- a/tests/Instances/Miscellaneous.hs
+++ b/tests/Instances/Miscellaneous.hs
@@ -4,7 +4,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Miscellaneous
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -16,18 +16,18 @@
 
 #include "HsBaseConfig.h"
 
-#if !(MIN_VERSION_QuickCheck(2,9,0))
-import Data.Version (Version(..))
-#endif
-
 import Foreign.Ptr (Ptr, nullPtr, plusPtr)
 
+import Generics.Deriving.Instances ()
+
+import Instances.Utils.GenericArbitrary (genericArbitrary)
+
 import Prelude ()
 import Prelude.Compat
 
 import System.Exit (ExitCode(..))
 
-import Test.QuickCheck (Arbitrary(..), oneof)
+import Test.QuickCheck (Arbitrary(..))
 
 #if MIN_VERSION_base(4,5,0)
 
@@ -53,16 +53,10 @@
 #endif
 
 instance Arbitrary ExitCode where
-    arbitrary = oneof [pure ExitSuccess, ExitFailure <$> arbitrary]
+    arbitrary = genericArbitrary
 
 instance Arbitrary (Ptr a) where
     arbitrary = plusPtr nullPtr <$> arbitrary
-
-#if !(MIN_VERSION_QuickCheck(2,9,0))
-instance Arbitrary Version where
-    arbitrary = pure $ Version [0] [""]
---     arbitrary = Version <$> arbitrary <*> arbitrary
-#endif
 
 #if MIN_VERSION_base(4,5,0)
 
diff --git a/tests/Instances/System/Console/Haskeline.hs b/tests/Instances/System/Console/Haskeline.hs
--- a/tests/Instances/System/Console/Haskeline.hs
+++ b/tests/Instances/System/Console/Haskeline.hs
@@ -1,7 +1,16 @@
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric      #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.System.Console.Haskeline
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -11,24 +20,39 @@
 -}
 module Instances.System.Console.Haskeline () where
 
-import Instances.Utils ((<@>))
+#if __GLASGOW_HASKELL__ >= 704
+import           GHC.Generics (Generic)
+#else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+#endif
 
-import Prelude ()
-import Prelude.Compat
+import           Instances.Utils ((<@>))
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
-import System.Console.Haskeline (Interrupt(..))
-import System.Console.Haskeline.Completion (Completion(..))
-import System.Console.Haskeline.History (History, addHistory, emptyHistory)
+import           Prelude ()
+import           Prelude.Compat
 
-import Test.QuickCheck (Arbitrary(..))
+import           System.Console.Haskeline (Interrupt(..))
+import           System.Console.Haskeline.Completion (Completion(..))
+import           System.Console.Haskeline.History (History, addHistory, emptyHistory)
 
+import           Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum)
+
+deriving instance Bounded Interrupt
+deriving instance Enum Interrupt
 instance Arbitrary Interrupt where
-    arbitrary = pure Interrupt
+    arbitrary = arbitraryBoundedEnum
 
 -- instance Arbitrary Prefs
 
 instance Arbitrary Completion where
-    arbitrary = Completion <$> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary History where
     arbitrary = addHistory <$> arbitrary <@> emptyHistory
+
+#if __GLASGOW_HASKELL__ >= 704
+deriving instance Generic Completion
+#else
+$(Generics.deriveAll0 ''Completion)
+#endif
diff --git a/tests/Instances/System/Console/Terminfo.hs b/tests/Instances/System/Console/Terminfo.hs
--- a/tests/Instances/System/Console/Terminfo.hs
+++ b/tests/Instances/System/Console/Terminfo.hs
@@ -1,12 +1,19 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP             #-}
 
 #if !defined(mingw32_HOST_OS)
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeFamilies    #-}
+
+# if __GLASGOW_HASKELL__ >= 706
+{-# LANGUAGE DataKinds       #-}
+# endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 #endif
 
 {-|
 Module:      Instances.System.Console.Terminfo
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,24 +24,17 @@
 module Instances.System.Console.Terminfo () where
 
 #if !defined(mingw32_HOST_OS)
-import Prelude ()
-import Prelude.Compat
-
-import System.Console.Terminfo.Color (Color(..))
-
-import Test.QuickCheck (Arbitrary(..), oneof)
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
+import           System.Console.Terminfo (Color, SetupTermError)
+import           Test.QuickCheck (Arbitrary(..))
 
 instance Arbitrary Color where
-    arbitrary = oneof [ pure Black
-                      , pure Red
-                      , pure Green
-                      , pure Yellow
-                      , pure Blue
-                      , pure Magenta
-                      , pure Cyan
-                      , pure White
-                      , ColorNumber <$> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
--- instance Arbitrary SetupTermError
+instance Arbitrary SetupTermError where
+    arbitrary = genericArbitrary
+
+$(Generics.deriveAll0 ''Color)
+$(Generics.deriveAll0 ''SetupTermError)
 #endif
diff --git a/tests/Instances/System/Directory.hs b/tests/Instances/System/Directory.hs
--- a/tests/Instances/System/Directory.hs
+++ b/tests/Instances/System/Directory.hs
@@ -1,8 +1,15 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP             #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeFamilies    #-}
+
+#if __GLASGOW_HASKELL__ >= 706
+{-# LANGUAGE DataKinds       #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.System.Directory
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -13,19 +20,12 @@
 module Instances.System.Directory () where
 
 #if MIN_VERSION_directory(1,1,0)
-import Control.Applicative ((<**>))
-
-import Prelude ()
-import Prelude.Compat
-
-import System.Directory (Permissions, emptyPermissions, setOwnerReadable,
-                         setOwnerWritable, setOwnerExecutable, setOwnerSearchable)
-
-import Test.QuickCheck (Arbitrary(..))
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
+import           System.Directory (Permissions)
+import           Test.QuickCheck (Arbitrary(..))
 
 instance Arbitrary Permissions where
-    arbitrary = ($ emptyPermissions) <$> (setOwnerReadable   <$> arbitrary)
-                                    <**> (setOwnerWritable   <$> arbitrary)
-                                    <**> (setOwnerExecutable <$> arbitrary)
-                                    <**> (setOwnerSearchable <$> arbitrary)
+    arbitrary = genericArbitrary
+$(Generics.deriveAll0 ''Permissions)
 #endif
diff --git a/tests/Instances/System/Locale.hs b/tests/Instances/System/Locale.hs
--- a/tests/Instances/System/Locale.hs
+++ b/tests/Instances/System/Locale.hs
@@ -1,7 +1,16 @@
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric      #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.System.Locale
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -11,13 +20,23 @@
 -}
 module Instances.System.Locale () where
 
-import Prelude ()
-import Prelude.Compat
+#if __GLASGOW_HASKELL__ >= 704
+import           GHC.Generics (Generic)
+#else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+#endif
 
-import System.Locale (TimeLocale(..))
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
-import Test.QuickCheck (Arbitrary(..))
+import           System.Locale (TimeLocale(..))
 
+import           Test.QuickCheck (Arbitrary(..))
+
 instance Arbitrary TimeLocale where
-    arbitrary = TimeLocale <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-                           <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
+
+#if __GLASGOW_HASKELL__ >= 704
+deriving instance Generic TimeLocale
+#else
+$(Generics.deriveAll0 ''TimeLocale)
+#endif
diff --git a/tests/Instances/System/Posix.hs b/tests/Instances/System/Posix.hs
--- a/tests/Instances/System/Posix.hs
+++ b/tests/Instances/System/Posix.hs
@@ -2,12 +2,19 @@
 
 #if !defined(mingw32_HOST_OS)
 {-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+# if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric      #-}
+# endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 #endif
 
 {-|
 Module:      Instances.System.Posix
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -18,39 +25,50 @@
 module Instances.System.Posix () where
 
 #if !defined(mingw32_HOST_OS)
-import Instances.Miscellaneous ()
+# if __GLASGOW_HASKELL__ >= 704
+import           GHC.Generics (Generic)
+# else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+# endif
 
-import Prelude ()
-import Prelude.Compat
+import           Instances.Miscellaneous ()
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
-import System.Posix.DynamicLinker (RTLDFlags(..), DL(..))
-import System.Posix.Process (ProcessStatus(..))
-import System.Posix.User (GroupEntry(..), UserEntry(..))
+import           Prelude ()
+import           Prelude.Compat
 
-import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum, oneof)
+import           System.Posix.DynamicLinker (RTLDFlags(..), DL(..))
+import           System.Posix.Process (ProcessStatus(..))
+import           System.Posix.User (GroupEntry(..), UserEntry(..))
 
+import           Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum)
+
 deriving instance Bounded RTLDFlags
 deriving instance Enum RTLDFlags
 instance Arbitrary RTLDFlags where
     arbitrary = arbitraryBoundedEnum
 
 instance Arbitrary DL where
-    arbitrary = oneof [pure Null, pure Next, pure Default, DLHandle <$> arbitrary]
+    arbitrary = genericArbitrary
 
 instance Arbitrary ProcessStatus where
-    arbitrary = oneof [ Exited     <$> arbitrary
-# if MIN_VERSION_unix(2,7,0)
-                      , Terminated <$> arbitrary <*> arbitrary
-# else
-                      , Terminated <$> arbitrary
-# endif
-                      , Stopped    <$> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary GroupEntry where
-    arbitrary = GroupEntry <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary UserEntry where
-    arbitrary = UserEntry <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-                          <*> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
+
+# if __GLASGOW_HASKELL__ >= 704
+deriving instance Generic DL
+deriving instance Generic ProcessStatus
+deriving instance Generic GroupEntry
+deriving instance Generic UserEntry
+# else
+$(Generics.deriveAll0 ''DL)
+$(Generics.deriveAll0 ''ProcessStatus)
+$(Generics.deriveAll0 ''GroupEntry)
+$(Generics.deriveAll0 ''UserEntry)
+# endif
 #endif
diff --git a/tests/Instances/System/Random.hs b/tests/Instances/System/Random.hs
--- a/tests/Instances/System/Random.hs
+++ b/tests/Instances/System/Random.hs
@@ -1,7 +1,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.System.Random
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/tests/Instances/System/Win32.hs b/tests/Instances/System/Win32.hs
--- a/tests/Instances/System/Win32.hs
+++ b/tests/Instances/System/Win32.hs
@@ -3,12 +3,19 @@
 #if defined(mingw32_HOST_OS)
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE TypeFamilies               #-}
+
+# if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric              #-}
+# endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 #endif
 
 {-|
 Module:      Instances.System.Win32
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -19,91 +26,71 @@
 module Instances.System.Win32 () where
 
 #if defined(mingw32_HOST_OS)
-import Instances.Miscellaneous ()
+# if __GLASGOW_HASKELL__ >= 704
+import           GHC.Generics (Generic)
+# else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+# endif
 
-import Prelude ()
-import Prelude.Compat
+import           Instances.Miscellaneous ()
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
-import System.Win32.DebugApi (DebugEventInfo(..), Exception(..))
-import System.Win32.File (BY_HANDLE_FILE_INFORMATION(..), WIN32_FILE_ATTRIBUTE_DATA(..))
-import System.Win32.Info (ProcessorArchitecture(..), SYSTEM_INFO(..))
-import System.Win32.Time (FILETIME(..), SYSTEMTIME(..),
-                          TIME_ZONE_INFORMATION(..), TimeZoneId(..))
+import           System.Win32.DebugApi (DebugEventInfo(..), Exception(..))
+import           System.Win32.File (BY_HANDLE_FILE_INFORMATION(..), WIN32_FILE_ATTRIBUTE_DATA(..))
+import           System.Win32.Info (ProcessorArchitecture(..), SYSTEM_INFO(..))
+import           System.Win32.Time (FILETIME(..), SYSTEMTIME(..),
+                                    TIME_ZONE_INFORMATION(..), TimeZoneId(..))
 
-import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum, oneof)
+import           Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum)
 
 instance Arbitrary DebugEventInfo where
-    arbitrary = oneof [ pure UnknownDebugEvent
-                      , Exception     <$> arbitrary <*> arbitrary
-                      , CreateThread  <$> arbitrary
-                      , CreateProcess <$> arbitrary <*> arbitrary <*> arbitrary
-                      , ExitThread    <$> arbitrary
-                      , ExitProcess   <$> arbitrary
-                      , LoadDll       <$> arbitrary
-                      , UnloadDll     <$> arbitrary
-                      , DebugString   <$> arbitrary <*> arbitrary <*> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary Exception where
-    arbitrary = oneof [ pure UnknownException
-                      , AccessViolation <$> arbitrary <*> arbitrary
-                      , pure ArrayBoundsExceeded
-                      , pure Breakpoint
-                      , pure DataTypeMisalignment
-                      , pure FltDenormalOperand
-                      , pure FltDivideByZero
-                      , pure FltInexactResult
-                      , pure FltInvalidOperation
-                      , pure FltOverflow
-                      , pure FltStackCheck
-                      , pure FltUnderflow
-                      , pure IllegalInstruction
-                      , pure InPageError
-                      , pure IntDivideByZero
-                      , pure IntOverflow
-                      , pure InvalidDisposition
-                      , pure NonContinuable
-                      , pure PrivilegedInstruction
-                      , pure SingleStep
-                      , pure StackOverflow
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary BY_HANDLE_FILE_INFORMATION where
-    arbitrary = BY_HANDLE_FILE_INFORMATION <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-                                           <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary WIN32_FILE_ATTRIBUTE_DATA where
-    arbitrary = WIN32_FILE_ATTRIBUTE_DATA <$> arbitrary <*> arbitrary <*> arbitrary
-                                          <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary ProcessorArchitecture where
-    arbitrary = oneof [ PaUnknown <$> arbitrary
-                      , pure PaIntel
-                      , pure PaMips
-                      , pure PaAlpha
-                      , pure PaPpc
-                      , pure PaIa64
-                      , pure PaIa32OnIa64
-                      , pure PaAmd64
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary SYSTEM_INFO where
-    arbitrary = SYSTEM_INFO <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-                            <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-                            <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 deriving instance Arbitrary FILETIME
 
 instance Arbitrary SYSTEMTIME where
-    arbitrary = SYSTEMTIME <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-                           <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary TIME_ZONE_INFORMATION where
-    arbitrary = TIME_ZONE_INFORMATION <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-                                      <*> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 deriving instance Bounded TimeZoneId
 deriving instance Enum TimeZoneId
 instance Arbitrary TimeZoneId where
     arbitrary = arbitraryBoundedEnum
+
+# if __GLASGOW_HASKELL__ >= 704
+deriving instance Generic DebugEventInfo
+deriving instance Generic Exception
+deriving instance Generic BY_HANDLE_FILE_INFORMATION
+deriving instance Generic WIN32_FILE_ATTRIBUTE_DATA
+deriving instance Generic ProcessorArchitecture
+deriving instance Generic SYSTEM_INFO
+deriving instance Generic SYSTEMTIME
+deriving instance Generic TIME_ZONE_INFORMATION
+# else
+$(Generics.deriveAll0 ''DebugEventInfo)
+$(Generics.deriveAll0 ''Exception)
+$(Generics.deriveAll0 ''BY_HANDLE_FILE_INFORMATION)
+$(Generics.deriveAll0 ''WIN32_FILE_ATTRIBUTE_DATA)
+$(Generics.deriveAll0 ''ProcessorArchitecture)
+$(Generics.deriveAll0 ''SYSTEM_INFO)
+$(Generics.deriveAll0 ''SYSTEMTIME)
+$(Generics.deriveAll0 ''TIME_ZONE_INFORMATION)
+# endif
 #endif
diff --git a/tests/Instances/Text/PrettyPrint.hs b/tests/Instances/Text/PrettyPrint.hs
--- a/tests/Instances/Text/PrettyPrint.hs
+++ b/tests/Instances/Text/PrettyPrint.hs
@@ -1,10 +1,17 @@
 {-# LANGUAGE CPP                        #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE TypeFamilies               #-}
+
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric              #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Text.PrettyPrint
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -15,22 +22,33 @@
 -}
 module Instances.Text.PrettyPrint () where
 
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
+
 import           Prelude ()
 import           Prelude.Compat
 
-import           Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum, oneof)
+import           Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum)
 
 import           Text.PrettyPrint.HughesPJ (Doc, Mode(..), Style(..),
                                             TextDetails(..), text)
 #if MIN_VERSION_pretty(1,1,2)
 import           Text.PrettyPrint.HughesPJClass (PrettyLevel(..))
 #endif
+
 #if MIN_VERSION_pretty(1,1,3)
 import qualified Text.PrettyPrint.Annotated.HughesPJ as Annot (Doc, text)
 import           Text.PrettyPrint.Annotated.HughesPJ (AnnotDetails(..), Span(..))
 import qualified Text.PrettyPrint.Annotated.HughesPJClass as Annot (PrettyLevel(..))
 #endif
 
+#if !(MIN_VERSION_pretty(1,1,2)) || MIN_VERSION_pretty(1,1,3)
+# if __GLASGOW_HASKELL__ >= 704
+import           GHC.Generics (Generic)
+# else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+# endif
+#endif
+
 instance Arbitrary Doc where
     arbitrary = text <$> arbitrary
 
@@ -40,10 +58,10 @@
     arbitrary = arbitraryBoundedEnum
 
 instance Arbitrary Style where
-    arbitrary = Style <$> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary TextDetails where
-    arbitrary = oneof [Chr <$> arbitrary, Str <$> arbitrary, PStr <$> arbitrary]
+    arbitrary = genericArbitrary
 
 #if MIN_VERSION_pretty(1,1,2)
 deriving instance Arbitrary PrettyLevel
@@ -51,14 +69,19 @@
 deriving instance Show Mode
 deriving instance Show Style
 deriving instance Show TextDetails
+
+# if __GLASGOW_HASKELL__ >= 704
+deriving instance Generic Style
+deriving instance Generic TextDetails
+# else
+$(Generics.deriveAll0 ''Style)
+$(Generics.deriveAll0 ''TextDetails)
+# endif
 #endif
 
 #if MIN_VERSION_pretty(1,1,3)
 instance Arbitrary a => Arbitrary (AnnotDetails a) where
-    arbitrary = oneof [ pure AnnotStart
-                      , NoAnnot <$> arbitrary <*> arbitrary
-                      , AnnotEnd <$> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
 instance Arbitrary (Annot.Doc a) where
     arbitrary = Annot.text <$> arbitrary
@@ -66,5 +89,13 @@
 deriving instance Arbitrary Annot.PrettyLevel
 
 instance Arbitrary a => Arbitrary (Span a) where
-    arbitrary = Span <$> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
+
+# if __GLASGOW_HASKELL__ >= 704
+deriving instance Generic (AnnotDetails a)
+deriving instance Generic (Span a)
+# else
+$(Generics.deriveAll0 ''AnnotDetails)
+$(Generics.deriveAll0 ''Span)
+# endif
 #endif
diff --git a/tests/Instances/Text/XHtml.hs b/tests/Instances/Text/XHtml.hs
--- a/tests/Instances/Text/XHtml.hs
+++ b/tests/Instances/Text/XHtml.hs
@@ -1,7 +1,16 @@
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE DeriveGeneric      #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Text.XHtml
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -11,14 +20,22 @@
 -}
 module Instances.Text.XHtml () where
 
-import Prelude ()
-import Prelude.Compat
+#if __GLASGOW_HASKELL__ >= 704
+import           GHC.Generics (Generic)
+#else
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
+#endif
 
-import Test.QuickCheck (Arbitrary(..), Gen)
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
-import Text.XHtml.Frameset (Html, HtmlAttr, HotLink(..), strAttr, toHtml)
-import Text.XHtml.Table (HtmlTable, cell)
+import           Prelude ()
+import           Prelude.Compat
 
+import           Test.QuickCheck (Arbitrary(..), Gen)
+
+import           Text.XHtml.Frameset (Html, HtmlAttr, HotLink(..), strAttr, toHtml)
+import           Text.XHtml.Table (HtmlTable, cell)
+
 instance Arbitrary Html where
     arbitrary = toHtml <$> (arbitrary :: Gen String)
 
@@ -26,7 +43,13 @@
     arbitrary = strAttr <$> arbitrary <*> arbitrary
 
 instance Arbitrary HotLink where
-    arbitrary = HotLink <$> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary HtmlTable where
     arbitrary = cell <$> (arbitrary :: Gen Html)
+
+#if __GLASGOW_HASKELL__ >= 704
+deriving instance Generic HotLink
+#else
+$(Generics.deriveAll0 ''HotLink)
+#endif
diff --git a/tests/Instances/Trace/Hpc.hs b/tests/Instances/Trace/Hpc.hs
--- a/tests/Instances/Trace/Hpc.hs
+++ b/tests/Instances/Trace/Hpc.hs
@@ -1,8 +1,16 @@
+{-# LANGUAGE CPP                #-}
 {-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+#if __GLASGOW_HASKELL__ >= 706
+{-# LANGUAGE DataKinds          #-}
+#endif
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-|
 Module:      Instances.Trace.Hpc
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -12,18 +20,21 @@
 -}
 module Instances.Trace.Hpc () where
 
-import Instances.Utils ((<@>))
+import qualified Generics.Deriving.TH as Generics (deriveAll0)
 
-import Prelude ()
-import Prelude.Compat
+import           Instances.Utils ((<@>))
+import           Instances.Utils.GenericArbitrary (genericArbitrary)
 
-import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum, oneof)
-import Test.QuickCheck.Instances ()
+import           Prelude ()
+import           Prelude.Compat
 
-import Trace.Hpc.Mix (Mix(..), MixEntry, BoxLabel(..), CondBox(..))
-import Trace.Hpc.Tix (Tix(..), TixModule(..))
-import Trace.Hpc.Util (HpcPos, Hash, toHpcPos)
+import           Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum)
+import           Test.QuickCheck.Instances ()
 
+import           Trace.Hpc.Mix (Mix(..), MixEntry, BoxLabel(..), CondBox(..))
+import           Trace.Hpc.Tix (Tix(..), TixModule(..))
+import           Trace.Hpc.Util (HpcPos, Hash, toHpcPos)
+
 instance Arbitrary Mix where
     arbitrary = Mix <$> arbitrary <*> arbitrary <*> arbitrary
                     <*> arbitrary <@> [fMixEntry]
@@ -31,11 +42,7 @@
 --                     <*> arbitrary <*> arbitrary
 
 instance Arbitrary BoxLabel where
-    arbitrary = oneof [ ExpBox      <$> arbitrary
-                      , TopLevelBox <$> arbitrary
-                      , LocalBox    <$> arbitrary
-                      , BinBox      <$> arbitrary <*> arbitrary
-                      ]
+    arbitrary = genericArbitrary
 
 deriving instance Bounded CondBox
 deriving instance Enum CondBox
@@ -43,17 +50,16 @@
     arbitrary = arbitraryBoundedEnum
 
 instance Arbitrary Tix where
-    arbitrary = Tix <$> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary TixModule where
-    arbitrary = TixModule <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
+    arbitrary = genericArbitrary
 
 instance Arbitrary HpcPos where
-    arbitrary = toHpcPos <$> ((,,,) <$> arbitrary <*> arbitrary
-                                    <*> arbitrary <*> arbitrary)
+    arbitrary = genericArbitrary
 
 instance Arbitrary Hash where
-    arbitrary = fromInteger <$> arbitrary
+    arbitrary = genericArbitrary
 
 -------------------------------------------------------------------------------
 -- Workarounds to make Arbitrary instances faster
@@ -61,3 +67,9 @@
 
 fMixEntry :: MixEntry
 fMixEntry = (toHpcPos (0, 1, 2, 3), ExpBox True)
+
+$(Generics.deriveAll0 ''BoxLabel)
+$(Generics.deriveAll0 ''Tix)
+$(Generics.deriveAll0 ''TixModule)
+$(Generics.deriveAll0 ''HpcPos)
+$(Generics.deriveAll0 ''Hash)
diff --git a/tests/Instances/Utils.hs b/tests/Instances/Utils.hs
--- a/tests/Instances/Utils.hs
+++ b/tests/Instances/Utils.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Instances.Utils
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
diff --git a/tests/Instances/Utils/GenericArbitrary.hs b/tests/Instances/Utils/GenericArbitrary.hs
new file mode 100644
--- /dev/null
+++ b/tests/Instances/Utils/GenericArbitrary.hs
@@ -0,0 +1,147 @@
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE KindSignatures       #-}
+{-# LANGUAGE MagicHash            #-}
+{-# LANGUAGE ScopedTypeVariables  #-}
+{-# LANGUAGE TypeOperators        #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+
+{-|
+Module:      Instances.Utils.GenericArbitrary
+Copyright:   (C) 2014-2017 Ryan Scott
+License:     BSD-style (see the file LICENSE)
+Maintainer:  Ryan Scott
+Stability:   Provisional
+Portability: GHC
+
+A generic default implemention of 'arbitrary'.
+
+Ideally, this should be a part of @QuickCheck@ itself
+(see https://github.com/nick8325/quickcheck/pull/40), but alas, it hasn't been
+merged yet. Until then, we'll have to define it ourselves.
+-}
+module Instances.Utils.GenericArbitrary (genericArbitrary) where
+
+import Generics.Deriving.Base
+
+import GHC.Exts (Char(..), Double(..), Float(..), Int(..), Word(..))
+
+import Prelude ()
+import Prelude.Compat
+
+import Test.QuickCheck (Arbitrary(..), Gen, choose)
+
+-- | `Gen` for generic instances in which each constructor has equal probability
+-- of being chosen.
+genericArbitrary :: (Generic a, GArbitrary (Rep a)) => Gen a
+genericArbitrary = to <$> gArbitrary
+
+class GArbitrary f where
+  gArbitrary :: Gen (f a)
+
+instance GArbitrary V1 where
+  -- Following the `Encode' V1` example in GHC.Generics.
+  gArbitrary = undefined
+
+instance GArbitrary U1 where
+  gArbitrary = return U1
+
+instance (GArbitrary a, GArbitrary b) => GArbitrary (a :*: b) where
+  gArbitrary = (:*:) <$> gArbitrary <*> gArbitrary
+
+instance ( SumSize    a, SumSize    b
+         , ChooseSum  a, ChooseSum  b ) => GArbitrary (a :+: b) where
+  gArbitrary = do
+    -- We cannot simply choose with equal probability between the left and
+    -- right part of the `a :+: b` (e.g. with `choose (False, True)`),
+    -- because GHC.Generics does not guarantee :+: to be balanced; even if it
+    -- did, it could only do so for sum types with 2^n alternatives.
+    -- If we did that and got a data structure of form `(a :+: (b :+: c))`,
+    -- then a would be chosen just as often as b and c together.
+    -- So we first have to compute the number of alternatives using `sumSize`,
+    -- and then uniformly sample a number in the corresponding range.
+    let size = unTagged2 (sumSize :: Tagged2 (a :+: b) Int)
+    x <- choose (1, size)
+    -- Optimisation:
+    -- We could just recursively call `gArbitrary` on the left orright branch
+    -- here, as in
+    --   if x <= sizeL
+    --     then L1 <$> gArbitrary
+    --     else R1 <$> gArbitrary
+    -- but this would unnecessarily sample again in the same sum type, and that
+    -- even though `x` completely determines which alternative to choose,
+    -- and sampling is slow because it needs IO and random numbers.
+    -- So instead we use `chooseSum x` to pick the x'th alternative from the
+    -- current sum type.
+    -- This made it around 50% faster for a sum type with 26 alternatives
+    -- on my computer.
+    chooseSum x
+
+instance GArbitrary a => GArbitrary (M1 i c a) where
+  gArbitrary = M1 <$> gArbitrary
+
+instance Arbitrary a => GArbitrary (K1 i a) where
+  gArbitrary = K1 <$> arbitrary
+
+instance GArbitrary UChar where
+  gArbitrary = do
+    C# c <- arbitrary
+    return (UChar c)
+
+instance GArbitrary UDouble where
+  gArbitrary = do
+    D# d <- arbitrary
+    return (UDouble d)
+
+instance GArbitrary UFloat where
+  gArbitrary = do
+    F# f <- arbitrary
+    return (UFloat f)
+
+instance GArbitrary UInt where
+  gArbitrary = do
+    I# i <- arbitrary
+    return (UInt i)
+
+instance GArbitrary UWord where
+  gArbitrary = do
+    W# w <- arbitrary
+    return (UWord w)
+
+newtype Tagged2 (s :: * -> *) b = Tagged2 {unTagged2 :: b}
+
+-- | Calculates the size of a sum type (numbers of alternatives).
+--
+-- Example: `data X = A | B | C` has `sumSize` 3.
+class SumSize f where
+  sumSize :: Tagged2 f Int
+
+-- Recursive case: Sum split `(:+:)`..
+instance (SumSize a, SumSize b) => SumSize (a :+: b) where
+  sumSize = Tagged2 $ unTagged2 (sumSize :: Tagged2 a Int) +
+                          unTagged2 (sumSize :: Tagged2 b Int)
+  {-# INLINE sumSize #-}
+
+-- Constructor base case.
+instance SumSize (C1 s a) where
+  sumSize = Tagged2 1
+  {-# INLINE sumSize #-}
+
+-- | This class takes an integer `x` and returns a `gArbitrary` value
+-- for the `x`'th alternative in a sum type.
+class ChooseSum f where
+  chooseSum :: Int -> Gen (f a)
+
+-- Recursive case: Check whether `x` lies in the left or the right side
+-- of the (:+:) split.
+instance (SumSize a, ChooseSum a, ChooseSum b) => ChooseSum (a :+: b) where
+  chooseSum x = do
+    let sizeL = unTagged2 (sumSize :: Tagged2 a Int)
+    if x <= sizeL
+      then L1 <$> chooseSum x
+      else R1 <$> chooseSum (x - sizeL)
+
+-- Constructor base case.
+instance (GArbitrary a) => ChooseSum (C1 s a) where
+  chooseSum 1 = gArbitrary
+  chooseSum _ = error "chooseSum: BUG"
diff --git a/tests/Spec/Compiler/HooplSpec.hs b/tests/Spec/Compiler/HooplSpec.hs
--- a/tests/Spec/Compiler/HooplSpec.hs
+++ b/tests/Spec/Compiler/HooplSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Compiler.HooplSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -14,12 +14,13 @@
                        Unique, UniqueMap, UniqueSet, C)
 import Compiler.Hoopl.Passes.Dominator (DominatorNode, DominatorTree, DPath)
 
+import Data.Proxy (Proxy(..))
+
 import Instances.Compiler.Hoopl ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.Compiler.Hoopl ()
 
@@ -29,22 +30,22 @@
 spec :: Spec
 spec = parallel $ do
     describe "Label" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Label -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Label)
     describe "LabelMap Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> LabelMap Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (LabelMap Char))
     describe "LabelSet" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> LabelSet -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy LabelSet)
     describe "Pointed C C Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Pointed C C Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Pointed C C Int))
     describe "Unique" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Unique -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Unique)
     describe "UniqueMap Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> UniqueMap Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (UniqueMap Char))
     describe "UniqueSet" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> UniqueSet -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy UniqueSet)
     describe "DominatorNode" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> DominatorNode -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy DominatorNode)
     describe "DominatorTree" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> DominatorTree -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy DominatorTree)
     describe "DPath" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> DPath -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy DPath)
diff --git a/tests/Spec/Control/Applicative/TransSpec.hs b/tests/Spec/Control/Applicative/TransSpec.hs
--- a/tests/Spec/Control/Applicative/TransSpec.hs
+++ b/tests/Spec/Control/Applicative/TransSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Control.Applicative.TransSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -13,12 +13,13 @@
 import Control.Applicative.Backwards (Backwards)
 import Control.Applicative.Lift      (Lift)
 
+import Data.Proxy (Proxy(..))
+
 import Instances.Control.Applicative.Trans ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.Control.Applicative.Trans ()
 
@@ -28,6 +29,6 @@
 spec :: Spec
 spec = parallel $ do
     describe "Backwards Maybe Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Backwards Maybe Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Backwards Maybe Int))
     describe "Lift Maybe Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Lift Maybe Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Lift Maybe Int))
diff --git a/tests/Spec/Control/Monad/TransSpec.hs b/tests/Spec/Control/Monad/TransSpec.hs
--- a/tests/Spec/Control/Monad/TransSpec.hs
+++ b/tests/Spec/Control/Monad/TransSpec.hs
@@ -1,7 +1,7 @@
 {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
 {-|
 Module:      Spec.Control.Monad.TransSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -19,12 +19,13 @@
 import qualified Control.Monad.Trans.Writer.Lazy   as WL (WriterT)
 import qualified Control.Monad.Trans.Writer.Strict as WS (WriterT)
 
+import           Data.Proxy (Proxy(..))
+
 import           Instances.Control.Monad.Trans ()
 
-import           Spec.Utils (prop_matchesTextShow)
+import           Spec.Utils (matchesTextShowSpec)
 
 import           Test.Hspec (Spec, describe, hspec, parallel)
-import           Test.Hspec.QuickCheck (prop)
 
 import           TextShow.Control.Monad.Trans ()
 
@@ -34,16 +35,16 @@
 spec :: Spec
 spec = parallel $ do
     describe "ErrorT Char Maybe Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ErrorT Char Maybe Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (ErrorT Char Maybe Int))
     describe "ExceptT Char Maybe Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ExceptT Char Maybe Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (ExceptT Char Maybe Int))
     describe "IdentityT Maybe Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> IdentityT Maybe Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (IdentityT Maybe Int))
     describe "ListT Maybe Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ListT Maybe Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (ListT Maybe Char))
     describe "Maybe [] Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> MaybeT [] Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (MaybeT [] Int))
     describe "lazy WriterT String Maybe Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> WL.WriterT String Maybe Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (WL.WriterT String Maybe Int))
     describe "strict WriterT String Maybe Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> WS.WriterT String Maybe Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (WS.WriterT String Maybe Int))
diff --git a/tests/Spec/Data/BifunctorSpec.hs b/tests/Spec/Data/BifunctorSpec.hs
--- a/tests/Spec/Data/BifunctorSpec.hs
+++ b/tests/Spec/Data/BifunctorSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Data.BifunctorSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,15 +17,16 @@
 import Data.Bifunctor.Join (Join)
 import Data.Bifunctor.Joker (Joker)
 import Data.Bifunctor.Product (Product)
+import Data.Bifunctor.Sum (Sum)
 import Data.Bifunctor.Tannen (Tannen)
 import Data.Bifunctor.Wrapped (WrappedBifunctor)
+import Data.Proxy (Proxy(..))
 
 import Instances.Data.Bifunctor ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.Data.Bifunctor ()
 
@@ -35,20 +36,22 @@
 spec :: Spec
 spec = parallel $ do
     describe "Biff Either [] Maybe Char Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Biff Either [] Maybe Char Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Biff Either [] Maybe Char Int))
     describe "Clown [] Char Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Clown [] Char Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Clown [] Char Int))
     describe "Fix Either Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Fix Either Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Fix Either Int))
     describe "Flip Either Int Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Flip Either Int Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Flip Either Int Char))
     describe "Join Either Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Join Either Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Join Either Int))
     describe "Joker [] Char Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Joker [] Char Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Joker [] Char Int))
     describe "Product Either ((,,) Bool) Int Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Product Either ((,,) Bool) Int Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Product Either ((,,) Bool) Int Char))
+    describe "Sum Either ((,,) Bool) Int Char" $
+        matchesTextShowSpec (Proxy :: Proxy (Sum Either ((,,) Bool) Int Char))
     describe "Tannen Maybe Either Int Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Tannen Maybe Either Int Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Tannen Maybe Either Int Char))
     describe "WrappedBifunctor Either Int Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> WrappedBifunctor Either Int Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (WrappedBifunctor Either Int Char))
diff --git a/tests/Spec/Data/BinarySpec.hs b/tests/Spec/Data/BinarySpec.hs
--- a/tests/Spec/Data/BinarySpec.hs
+++ b/tests/Spec/Data/BinarySpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Data.BinarySpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -11,13 +11,13 @@
 module Spec.Data.BinarySpec (main, spec) where
 
 import Data.Binary.Get.Internal (Decoder)
+import Data.Proxy (Proxy(..))
 
 import Instances.Data.Binary ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.Data.Binary ()
 
@@ -26,4 +26,4 @@
 
 spec :: Spec
 spec = parallel . describe "Decoder Int" $
-    prop "TextShow instance" (prop_matchesTextShow :: Int -> Decoder Int -> Bool)
+    matchesTextShowSpec (Proxy :: Proxy (Decoder Int))
diff --git a/tests/Spec/Data/ContainersSpec.hs b/tests/Spec/Data/ContainersSpec.hs
--- a/tests/Spec/Data/ContainersSpec.hs
+++ b/tests/Spec/Data/ContainersSpec.hs
@@ -1,6 +1,8 @@
+{-# LANGUAGE CPP #-}
+
 {-|
 Module:      Spec.Data.ContainersSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,19 +12,23 @@
 -}
 module Spec.Data.ContainersSpec (main, spec) where
 
+import Data.Graph (SCC)
 import Data.IntMap (IntMap)
 import Data.IntSet (IntSet)
 import Data.Map (Map)
+import Data.Proxy (Proxy(..))
 import Data.Sequence (Seq, ViewL, ViewR)
 import Data.Set (Set)
 import Data.Tree (Tree)
 
 import Instances.Data.Containers ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
+#if MIN_VERSION_containers(0,5,9)
+import Spec.Utils (matchesTextShow1Spec, matchesTextShow2Spec)
+#endif
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 import Test.QuickCheck.Instances ()
 
 import TextShow.Data.Containers ()
@@ -32,19 +38,56 @@
 
 spec :: Spec
 spec = parallel $ do
-    describe "IntMap Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> IntMap Char -> Bool)
+    describe "IntMap Char" $ do
+        let p :: Proxy (IntMap Char)
+            p = Proxy
+        matchesTextShowSpec  p
+#if MIN_VERSION_containers(0,5,9)
+        matchesTextShow1Spec p
+#endif
     describe "IntSet" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> IntSet -> Bool)
-    describe "Map Char Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Map Char Char -> Bool)
-    describe "Sequence Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Seq Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy IntSet)
+    describe "Map Char Char" $ do
+        let p :: Proxy (Map Char Char)
+            p = Proxy
+        matchesTextShowSpec  p
+#if MIN_VERSION_containers(0,5,9)
+        matchesTextShow1Spec p
+        matchesTextShow2Spec p
+#endif
+    describe "Sequence Char" $ do
+        let p :: Proxy (Seq Char)
+            p = Proxy
+        matchesTextShowSpec  p
+#if MIN_VERSION_containers(0,5,9)
+        matchesTextShow1Spec p
+#endif
     describe "ViewL Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ViewL Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (ViewL Char))
     describe "ViewR Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ViewR Char -> Bool)
-    describe "Set Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Set Char -> Bool)
-    describe "Tree Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Tree Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (ViewR Char))
+    describe "SCC Char" $ do
+        let p :: Proxy (SCC Char)
+            p = Proxy
+        matchesTextShowSpec  p
+#if MIN_VERSION_containers(0,5,9)
+        matchesTextShow1Spec p
+#endif
+    describe "Set Char" $ do
+        let p :: Proxy (Set Char)
+            p = Proxy
+        matchesTextShowSpec  p
+#if MIN_VERSION_containers(0,5,9)
+        matchesTextShow1Spec p
+#endif
+    describe "Tree Char" $ do
+        let p :: Proxy (Tree Char)
+            p = Proxy
+        matchesTextShowSpec  p
+#if MIN_VERSION_containers(0,5,9)
+        {-
+        Disabled for now until a version of containers incorporating
+        https://github.com/haskell/containers/pull/381 has been released.
+        -}
+        -- matchesTextShow1Spec p
+#endif
diff --git a/tests/Spec/Data/Functor/TransSpec.hs b/tests/Spec/Data/Functor/TransSpec.hs
--- a/tests/Spec/Data/Functor/TransSpec.hs
+++ b/tests/Spec/Data/Functor/TransSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Data.Functor.TransSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -15,13 +15,13 @@
 import Data.Functor.Product  (Product)
 import Data.Functor.Reverse  (Reverse)
 import Data.Functor.Sum      (Sum)
+import Data.Proxy            (Proxy(..))
 
 import Instances.Data.Functor.Trans ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.Data.Functor.Trans ()
 
@@ -31,12 +31,12 @@
 spec :: Spec
 spec = parallel $ do
     describe "Compose Maybe (Either Int) Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Compose Maybe (Either Int) Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Compose Maybe (Either Int) Char))
     describe "Constant Int Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Constant Int Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Constant Int Char))
     describe "Product Maybe (Either Int) Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Product Maybe (Either Int) Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Product Maybe (Either Int) Char))
     describe "Reverse Maybe Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Reverse Maybe Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Reverse Maybe Int))
     describe "Sum Maybe (Either Int) Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Sum Maybe (Either Int) Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Sum Maybe (Either Int) Char))
diff --git a/tests/Spec/Data/TaggedSpec.hs b/tests/Spec/Data/TaggedSpec.hs
--- a/tests/Spec/Data/TaggedSpec.hs
+++ b/tests/Spec/Data/TaggedSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Data.TaggedSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,14 +10,14 @@
 -}
 module Spec.Data.TaggedSpec (main, spec) where
 
+import Data.Proxy (Proxy(..))
 import Data.Tagged (Tagged)
 
 import Instances.Data.Tagged ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.Data.Tagged ()
 
@@ -26,4 +26,4 @@
 
 spec :: Spec
 spec = parallel . describe "Tagged Char Int" $
-    prop "TextShow instance" (prop_matchesTextShow :: Int -> Tagged Char Int -> Bool)
+    matchesTextShowSpec (Proxy :: Proxy (Tagged Char Int))
diff --git a/tests/Spec/Data/TimeSpec.hs b/tests/Spec/Data/TimeSpec.hs
--- a/tests/Spec/Data/TimeSpec.hs
+++ b/tests/Spec/Data/TimeSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Data.TimeSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,15 +10,15 @@
 -}
 module Spec.Data.TimeSpec (main, spec) where
 
+import Data.Proxy (Proxy(..))
 import Data.Time.Calendar (Day)
 import Data.Time.Clock (DiffTime, UTCTime, NominalDiffTime)
 import Data.Time.Clock.TAI (AbsoluteTime)
 import Data.Time.LocalTime (TimeZone, TimeOfDay, LocalTime, ZonedTime)
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 import Test.QuickCheck.Instances ()
 
 import TextShow.Data.Time ()
@@ -29,20 +29,20 @@
 spec :: Spec
 spec = parallel $ do
     describe "Day" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Day -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Day)
     describe "DiffTime" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> DiffTime -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy DiffTime)
     describe "UTCTime" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> UTCTime -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy UTCTime)
     describe "NominalDiffTime" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> NominalDiffTime -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy NominalDiffTime)
     describe "AbsoluteTime" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> AbsoluteTime -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy AbsoluteTime)
     describe "TimeZone" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> TimeZone -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TimeZone)
     describe "TimeOfDay" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> TimeOfDay -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TimeOfDay)
     describe "LocalTime" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> LocalTime -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy LocalTime)
     describe "ZonedTime" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ZonedTime -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy ZonedTime)
diff --git a/tests/Spec/Data/UnorderedContainersSpec.hs b/tests/Spec/Data/UnorderedContainersSpec.hs
--- a/tests/Spec/Data/UnorderedContainersSpec.hs
+++ b/tests/Spec/Data/UnorderedContainersSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Data.UnorderedContainersSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -12,11 +12,11 @@
 
 import Data.HashMap.Lazy (HashMap)
 import Data.HashSet (HashSet)
+import Data.Proxy (Proxy(..))
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 import Test.QuickCheck.Instances ()
 
 import TextShow.Data.UnorderedContainers ()
@@ -27,6 +27,6 @@
 spec :: Spec
 spec = parallel $ do
     describe "HashMap Char Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> HashMap Char Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (HashMap Char Char))
     describe "HashSet Char" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> HashSet Char -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (HashSet Char))
diff --git a/tests/Spec/GHC/LanguageExtensions/TypeSpec.hs b/tests/Spec/GHC/LanguageExtensions/TypeSpec.hs
--- a/tests/Spec/GHC/LanguageExtensions/TypeSpec.hs
+++ b/tests/Spec/GHC/LanguageExtensions/TypeSpec.hs
@@ -1,7 +1,8 @@
 {-# LANGUAGE CPP #-}
+
 {-|
 Module:      Spec.GHC.LanguageExtensions.TypeSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -16,16 +17,12 @@
 
 import Test.Hspec (Spec, hspec, parallel)
 
-#if defined(MIN_VERSION_ghc_boot)
+#if defined(MIN_VERSION_ghc_boot_th)
+import Data.Proxy (Proxy(..))
 import GHC.LanguageExtensions.Type (Extension)
-
 import Instances.GHC.LanguageExtensions.Type ()
-
-import Spec.Utils (prop_matchesTextShow)
-
+import Spec.Utils (matchesTextShowSpec)
 import Test.Hspec (describe)
-import Test.Hspec.QuickCheck (prop)
-
 import TextShow.GHC.LanguageExtensions.Type ()
 #endif
 
@@ -34,9 +31,9 @@
 
 spec :: Spec
 spec = parallel $ do
-#if defined(MIN_VERSION_ghc_boot)
+#if defined(MIN_VERSION_ghc_boot_th)
     describe "Extension" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Extension -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Extension)
 #else
     pure ()
 #endif
diff --git a/tests/Spec/GHC/PackageDbSpec.hs b/tests/Spec/GHC/PackageDbSpec.hs
deleted file mode 100644
--- a/tests/Spec/GHC/PackageDbSpec.hs
+++ /dev/null
@@ -1,60 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-|
-Module:      Spec.GHC.PackageDbSpec
-Copyright:   (C) 2014-2016 Ryan Scott
-License:     BSD-style (see the file LICENSE)
-Maintainer:  Ryan Scott
-Stability:   Provisional
-Portability: GHC
-
-@hspec@ tests for data types in the "GHC.PackageDb" module.
--}
-module Spec.GHC.PackageDbSpec (main, spec) where
-
-import Prelude ()
-import Prelude.Compat
-
-import Test.Hspec (Spec, hspec, parallel)
-
-#if defined(MIN_VERSION_ghc_boot)
-import GHC.PackageDb
-
-import Instances.GHC.PackageDb ()
-
-import Spec.Utils (prop_matchesTextShow)
-
-import Test.Hspec (describe)
-import Test.Hspec.QuickCheck (prop)
-
-import TextShow.GHC.PackageDb ()
-
-ipiString :: String
-# if __GLASGOW_HASKELL__ >= 801
-type IPI = InstalledPackageInfo Int Int Int Int Int
-ipiString = "InstalledPackageInfo Int Int Int Int Int"
-# else
-type IPI = InstalledPackageInfo Int Int Int Int
-ipiString = "InstalledPackageInfo Int Int Int Int"
-# endif
-#endif
-
-main :: IO ()
-main = hspec spec
-
-spec :: Spec
-spec = parallel $ do
-#if defined(MIN_VERSION_ghc_boot)
-    describe ipiString $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> IPI -> Bool)
-# if __GLASGOW_HASKELL__ >= 801
-    describe "DbModule Int Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> DbModule Int Int -> Bool)
-# else
-    describe "OriginalModule Int Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> OriginalModule Int Int -> Bool)
-    describe "ExposedModule Int Int" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ExposedModule Int Int -> Bool)
-# endif
-#else
-    pure ()
-#endif
diff --git a/tests/Spec/Language/Haskell/THSpec.hs b/tests/Spec/Language/Haskell/THSpec.hs
--- a/tests/Spec/Language/Haskell/THSpec.hs
+++ b/tests/Spec/Language/Haskell/THSpec.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-|
 Module:      Spec.Language.Haskell.THSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -11,13 +11,14 @@
 -}
 module Spec.Language.Haskell.THSpec (main, spec) where
 
+import Data.Proxy (Proxy(..))
+
 import Instances.Language.Haskell.TH ()
 
-import Language.Haskell.TH.Instances ()
 import Language.Haskell.TH.PprLib
 import Language.Haskell.TH.Syntax
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
 import Test.Hspec.QuickCheck (prop)
@@ -32,153 +33,159 @@
 spec = parallel $ do
 #if MIN_VERSION_template_haskell(2,9,0)
     describe "AnnLookup" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> AnnLookup -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy AnnLookup)
     describe "AnnTarget" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> AnnTarget -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy AnnTarget)
 #endif
 #if MIN_VERSION_template_haskell(2,11,0)
     describe "Bang" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Bang -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Bang)
 #endif
     describe "Body" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Body -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Body)
     describe "Callconv" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Callconv -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Callconv)
 #if MIN_VERSION_template_haskell(2,5,0) && !(MIN_VERSION_template_haskell(2,7,0))
     describe "ClassInstance" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> ClassInstance -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy ClassInstance)
 #endif
     describe "Clause" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Clause -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Clause)
     describe "Con" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Con -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Con)
     describe "Dec" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Dec -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Dec)
 #if MIN_VERSION_template_haskell(2,11,0)
     describe "DecidedStrictness" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> DecidedStrictness -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy DecidedStrictness)
 #endif
+#if MIN_VERSION_template_haskell(2,12,0)
+    describe "DerivClause" $
+        matchesTextShowSpec (Proxy :: Proxy DerivClause)
+    describe "DerivStrategy" $
+        matchesTextShowSpec (Proxy :: Proxy DerivStrategy)
+#endif
     describe "Doc" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Doc -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Doc)
     describe "Exp" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Exp -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Exp)
     describe "FamFlavour" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> FamFlavour -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy FamFlavour)
 #if MIN_VERSION_template_haskell(2,11,0)
     describe "FamilyResultSig" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> FamilyResultSig -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy FamilyResultSig)
 #endif
     describe "Fixity" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Fixity -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Fixity)
     describe "FixityDirection" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> FixityDirection -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy FixityDirection)
     describe "Foreign" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Foreign -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Foreign)
     describe "FunDep" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> FunDep -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy FunDep)
     describe "Guard" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Guard -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Guard)
     describe "Info" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Info -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Info)
 #if MIN_VERSION_template_haskell(2,11,0)
     describe "InjectivityAnn" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> InjectivityAnn -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy InjectivityAnn)
 #endif
 #if MIN_VERSION_template_haskell(2,8,0)
     describe "Inline" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Inline -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Inline)
 #else
     describe "InlineSpec" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> InlineSpec -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy InlineSpec)
 #endif
     describe "Kind" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Kind -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Kind)
     describe "Lit" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Lit -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Lit)
     describe "Loc" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Loc -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Loc)
     describe "Match" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Match -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Match)
     describe "ModName" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> ModName -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy ModName)
 #if MIN_VERSION_template_haskell(2,9,0)
     describe "Module" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Module -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Module)
     describe "ModuleInfo" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> ModuleInfo -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy ModuleInfo)
 #endif
     describe "Name" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Name -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Name)
     describe "showbName'" $
         prop "has the same output as showName" prop_showName'
     describe "NameFlavour" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> NameFlavour -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy NameFlavour)
     describe "NameSpace" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> NameSpace -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy NameSpace)
     describe "OccName" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> OccName -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy OccName)
 #if MIN_VERSION_template_haskell(2,11,0)
     describe "Overlap" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Overlap -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Overlap)
 #endif
     describe "Pat" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Pat -> Bool)
-#if __GLASGOW_HASKELL__ >= 801
+        matchesTextShowSpec (Proxy :: Proxy Pat)
+#if MIN_VERSION_template_haskell(2,12,0)
     describe "PatSynArgs" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> PatSynArgs -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy PatSynArgs)
     describe "PatSynDir" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> PatSynDir -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy PatSynDir)
 #endif
 #if MIN_VERSION_template_haskell(2,8,0)
     describe "Phases" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Phases -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Phases)
 #endif
     describe "PkgName" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> PkgName -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy PkgName)
     describe "Pred" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Pred -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Pred)
     describe "Pragma" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Pragma -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Pragma)
     describe "Range" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Range -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Range)
 #if MIN_VERSION_template_haskell(2,9,0)
     describe "Role" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Role -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Role)
 #endif
 #if MIN_VERSION_template_haskell(2,8,0)
     describe "RuleBndr" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> RuleBndr -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy RuleBndr)
     describe "RuleMatch" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> RuleMatch -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy RuleMatch)
 #endif
     describe "Safety" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Safety -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Safety)
 #if MIN_VERSION_template_haskell(2,11,0)
     describe "SourceStrictness" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> SourceStrictness -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy SourceStrictness)
     describe "SourceUnpackedness" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> SourceUnpackedness -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy SourceUnpackedness)
 #endif
     describe "Stmt" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Stmt -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Stmt)
     describe "Strict" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Strict -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Strict)
 #if MIN_VERSION_template_haskell(2,8,0)
     describe "TyLit" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> TyLit -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TyLit)
 #endif
     describe "Type" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> Type -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Type)
 #if MIN_VERSION_template_haskell(2,11,0)
     describe "TypeFamilyHead" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> TypeFamilyHead -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TypeFamilyHead)
 #endif
 #if MIN_VERSION_template_haskell(2,9,0)
     describe "TySynEqn" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> TySynEqn -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TySynEqn)
 #endif
     describe "TyVarBndr" $
-        prop "TextShow instance"               (prop_matchesTextShow :: Int -> TyVarBndr -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TyVarBndr)
 
 -- | Verifies that `showName'` and `showbName'` have the same output.
 prop_showName' :: NameIs -> Name -> Bool
diff --git a/tests/Spec/System/Console/HaskelineSpec.hs b/tests/Spec/System/Console/HaskelineSpec.hs
--- a/tests/Spec/System/Console/HaskelineSpec.hs
+++ b/tests/Spec/System/Console/HaskelineSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.System.Console.HaskelineSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,16 +10,17 @@
 -}
 module Spec.System.Console.HaskelineSpec (main, spec) where
 
+import Data.Proxy (Proxy(..))
+
 import Instances.System.Console.Haskeline ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import System.Console.Haskeline (Interrupt, defaultPrefs)
 import System.Console.Haskeline.Completion (Completion)
 import System.Console.Haskeline.History (History)
 
 import Test.Hspec (Spec, describe, hspec, it, parallel, shouldBe)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow (FromStringShow(..), showb)
 import TextShow.System.Console.Haskeline ()
@@ -30,12 +31,13 @@
 spec :: Spec
 spec = parallel $ do
     describe "Interrupt" $
-        prop "TextShow instance"                                  (prop_matchesTextShow :: Int -> Interrupt -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Interrupt)
 --     describe "Prefs" $
---         prop "TextShow instance"                                  (prop_matchesTextShow :: Int -> Prefs -> Bool)
+--         matchesTextShowSpec (Proxy :: Proxy Prefs)
     describe "defaultPrefs" $
-        it "should have coinciding string and text Show output" $ showb (FromStringShow defaultPrefs) `shouldBe` showb defaultPrefs
+        it "should have coinciding string and text Show output" $
+            showb (FromStringShow defaultPrefs) `shouldBe` showb defaultPrefs
     describe "Completion" $
-        prop "TextShow instance"                                  (prop_matchesTextShow :: Int -> Completion -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Completion)
     describe "History" $
-        prop "TextShow instance"                                  (prop_matchesTextShow :: Int -> History -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy History)
diff --git a/tests/Spec/System/Console/TerminfoSpec.hs b/tests/Spec/System/Console/TerminfoSpec.hs
--- a/tests/Spec/System/Console/TerminfoSpec.hs
+++ b/tests/Spec/System/Console/TerminfoSpec.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-|
 Module:      Spec.System.Console.TerminfoSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,15 +17,11 @@
 import Test.Hspec (Spec, hspec, parallel)
 
 #if !defined(mingw32_HOST_OS)
+import Data.Proxy (Proxy(..))
 import Instances.System.Console.Terminfo ()
-
-import Spec.Utils (prop_matchesTextShow)
-
-import System.Console.Terminfo.Color (Color)
-
+import Spec.Utils (matchesTextShowSpec)
+import System.Console.Terminfo (Color, SetupTermError)
 import Test.Hspec (describe)
-import Test.Hspec.QuickCheck (prop)
-
 import TextShow.System.Console.Terminfo ()
 #endif
 
@@ -36,9 +32,9 @@
 spec = parallel $ do
 #if !defined(mingw32_HOST_OS)
     describe "Color" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Color -> Bool)
---     describe "SetupTermError" $
---         prop "TextShow instance" (prop_matchesTextShow :: Int -> SetupTermError -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Color)
+    describe "SetupTermError" $
+        matchesTextShowSpec (Proxy :: Proxy SetupTermError)
 #else
     pure ()
 #endif
diff --git a/tests/Spec/System/DirectorySpec.hs b/tests/Spec/System/DirectorySpec.hs
--- a/tests/Spec/System/DirectorySpec.hs
+++ b/tests/Spec/System/DirectorySpec.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-|
 Module:      Spec.System.DirectorySpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,15 +17,11 @@
 import Test.Hspec (Spec, hspec, parallel)
 
 #if MIN_VERSION_directory(1,1,0)
+import Data.Proxy (Proxy(..))
 import Instances.System.Directory ()
-
-import Spec.Utils (prop_matchesTextShow)
-
+import Spec.Utils (matchesTextShowSpec)
 import System.Directory (Permissions)
-
 import Test.Hspec (describe)
-import Test.Hspec.QuickCheck (prop)
-
 import TextShow.System.Directory ()
 #endif
 
@@ -36,7 +32,7 @@
 spec = parallel $
 #if MIN_VERSION_directory(1,1,0)
     describe "Permissions" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Permissions -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Permissions)
 #else
     pure ()
 #endif
diff --git a/tests/Spec/System/LocaleSpec.hs b/tests/Spec/System/LocaleSpec.hs
--- a/tests/Spec/System/LocaleSpec.hs
+++ b/tests/Spec/System/LocaleSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.System.LocaleSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,15 +10,11 @@
 -}
 module Spec.System.LocaleSpec (main, spec) where
 
+import Data.Proxy (Proxy(..))
 import Instances.System.Locale ()
-
-import Spec.Utils (prop_matchesTextShow)
-
+import Spec.Utils (matchesTextShowSpec)
 import System.Locale (TimeLocale)
-
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
-
 import TextShow.System.Locale ()
 
 main :: IO ()
@@ -26,4 +22,4 @@
 
 spec :: Spec
 spec = parallel . describe "TimeLocale" $
-    prop "TextShow instance" (prop_matchesTextShow :: Int -> TimeLocale -> Bool)
+    matchesTextShowSpec (Proxy :: Proxy TimeLocale)
diff --git a/tests/Spec/System/PosixSpec.hs b/tests/Spec/System/PosixSpec.hs
--- a/tests/Spec/System/PosixSpec.hs
+++ b/tests/Spec/System/PosixSpec.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-|
 Module:      Spec.System.PosixSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,16 +17,17 @@
 import Test.Hspec (Spec, hspec, parallel)
 
 #if !defined(mingw32_HOST_OS)
+import Data.Proxy (Proxy(..))
+
 import Instances.System.Posix ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import System.Posix.DynamicLinker (RTLDFlags, DL)
 import System.Posix.Process (ProcessStatus)
 import System.Posix.User (GroupEntry, UserEntry)
 
 import Test.Hspec (describe)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.System.Posix ()
 #endif
@@ -38,15 +39,15 @@
 spec = parallel $ do
 #if !defined(mingw32_HOST_OS)
     describe "RTLDFlags" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> RTLDFlags -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy RTLDFlags)
     describe "DL" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> DL -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy DL)
     describe "ProcessStatus" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ProcessStatus -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy ProcessStatus)
     describe "GroupEntry" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> GroupEntry -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy GroupEntry)
     describe "UserEntry" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> UserEntry -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy UserEntry)
 #else
     pure ()
 #endif
diff --git a/tests/Spec/System/RandomSpec.hs b/tests/Spec/System/RandomSpec.hs
--- a/tests/Spec/System/RandomSpec.hs
+++ b/tests/Spec/System/RandomSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.System.RandomSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,15 +10,11 @@
 -}
 module Spec.System.RandomSpec (main, spec) where
 
+import Data.Proxy (Proxy(..))
 import Instances.System.Random ()
-
-import Spec.Utils (prop_matchesTextShow)
-
+import Spec.Utils (matchesTextShowSpec)
 import System.Random (StdGen)
-
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
-
 import TextShow.System.Random ()
 
 main :: IO ()
@@ -26,4 +22,4 @@
 
 spec :: Spec
 spec = parallel . describe "StdGen" $
-    prop "TextShow instance" (prop_matchesTextShow :: Int -> StdGen -> Bool)
+    matchesTextShowSpec (Proxy :: Proxy StdGen)
diff --git a/tests/Spec/System/TimeSpec.hs b/tests/Spec/System/TimeSpec.hs
--- a/tests/Spec/System/TimeSpec.hs
+++ b/tests/Spec/System/TimeSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.System.TimeSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,12 +10,13 @@
 -}
 module Spec.System.TimeSpec (main, spec) where
 
-import Spec.Utils (prop_matchesTextShow)
+import Data.Proxy (Proxy(..))
 
+import Spec.Utils (matchesTextShowSpec)
+
 import System.Time (ClockTime, TimeDiff, CalendarTime, Month, Day)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 import Test.QuickCheck.Instances ()
 
 import TextShow.System.Time ()
@@ -26,12 +27,12 @@
 spec :: Spec
 spec = parallel $ do
     describe "ClockTime" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ClockTime -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy ClockTime)
     describe "TimeDiff" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> TimeDiff -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TimeDiff)
     describe "CalendarTime" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> CalendarTime -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy CalendarTime)
     describe "Month" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Month -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Month)
     describe "Day" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Day -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Day)
diff --git a/tests/Spec/System/Win32Spec.hs b/tests/Spec/System/Win32Spec.hs
--- a/tests/Spec/System/Win32Spec.hs
+++ b/tests/Spec/System/Win32Spec.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-|
 Module:      Spec.System.Win32Spec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -17,9 +17,11 @@
 import Test.Hspec (Spec, hspec, parallel)
 
 #if defined(mingw32_HOST_OS)
+import Data.Proxy (Proxy(..))
+
 import Instances.System.Win32 ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import System.Win32.DebugApi (DebugEventInfo, Exception)
 import System.Win32.File (BY_HANDLE_FILE_INFORMATION, WIN32_FILE_ATTRIBUTE_DATA)
@@ -27,7 +29,6 @@
 import System.Win32.Time (FILETIME, SYSTEMTIME, TIME_ZONE_INFORMATION, TimeZoneId)
 
 import Test.Hspec (describe)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.System.Win32 ()
 #endif
@@ -39,25 +40,25 @@
 spec = parallel $ do
 #if defined(mingw32_HOST_OS)
     describe "DebugEventInfo" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> DebugEventInfo -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy DebugEventInfo)
     describe "Exception" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Exception -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Exception)
     describe "BY_HANDLE_FILE_INFORMATION" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> BY_HANDLE_FILE_INFORMATION -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy BY_HANDLE_FILE_INFORMATION)
     describe "WIN32_FILE_ATTRIBUTE_DATA" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> WIN32_FILE_ATTRIBUTE_DATA -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy WIN32_FILE_ATTRIBUTE_DATA)
     describe "ProcessorArchitecture" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> ProcessorArchitecture -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy ProcessorArchitecture)
     describe "SYSTEM_INFO" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> SYSTEM_INFO -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy SYSTEM_INFO)
     describe "FILETIME" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> FILETIME -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy FILETIME)
     describe "SYSTEMTIME" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> SYSTEMTIME -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy SYSTEMTIME)
     describe "TIME_ZONE_INFORMATION" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> TIME_ZONE_INFORMATION -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TIME_ZONE_INFORMATION)
     describe "TimeZoneId" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> TimeZoneId -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TimeZoneId)
 #else
     pure ()
 #endif
diff --git a/tests/Spec/Text/PrettyPrintSpec.hs b/tests/Spec/Text/PrettyPrintSpec.hs
--- a/tests/Spec/Text/PrettyPrintSpec.hs
+++ b/tests/Spec/Text/PrettyPrintSpec.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE CPP #-}
 {-|
 Module:      Spec.Text.PrettyPrintSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -11,15 +11,17 @@
 -}
 module Spec.Text.PrettyPrintSpec (main, spec) where
 
+import           Data.Proxy (Proxy(..))
+
 import           Instances.Text.PrettyPrint ()
 
-import           Spec.Utils (prop_matchesTextShow)
+import           Spec.Utils (matchesTextShowSpec)
 #if MIN_VERSION_pretty(1,1,2)
-import           Spec.Utils (prop_genericTextShow)
+import           Spec.Utils (genericTextShowSpec)
 #endif
 
 import           Test.Hspec (Spec, describe, hspec, parallel)
-import           Test.Hspec.QuickCheck (prop)
+-- import           Test.Hspec.QuickCheck (prop)
 
 import           Text.PrettyPrint.HughesPJ (Doc, Mode, Style, TextDetails {-, renderStyle -})
 #if MIN_VERSION_pretty(1,1,2)
@@ -39,38 +41,44 @@
 spec :: Spec
 spec = parallel $ do
     describe "Doc" $
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> Doc -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Doc)
     -- TODO: Figure out why this randomly stalls forever
 --     describe "renderStyleB" $ do
 --         prop "has the same output as renderStyle" prop_renderStyle
     describe "Mode" $ do
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> Mode -> Bool)
+        let p :: Proxy Mode
+            p = Proxy
+        matchesTextShowSpec p
 #if MIN_VERSION_pretty(1,1,2)
-        prop "generic TextShow"                  (prop_genericTextShow :: Int -> Mode -> Bool)
+        genericTextShowSpec p
 #endif
     describe "Style" $ do
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> Style -> Bool)
+        let p :: Proxy Style
+            p = Proxy
+        matchesTextShowSpec p
 #if MIN_VERSION_pretty(1,1,2)
-        prop "generic TextShow"                  (prop_genericTextShow :: Int -> Style -> Bool)
+        genericTextShowSpec p
 #endif
     describe "TextDetails" $ do
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> TextDetails -> Bool)
+        let p :: Proxy TextDetails
+            p = Proxy
+        matchesTextShowSpec p
 #if MIN_VERSION_pretty(1,1,2)
-        prop "generic TextShow"                  (prop_genericTextShow :: Int -> TextDetails -> Bool)
+        genericTextShowSpec p
 #endif
 #if MIN_VERSION_pretty(1,1,2)
     describe "PrettyLevel" $
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> PrettyLevel -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy PrettyLevel)
 #endif
 #if MIN_VERSION_pretty(1,1,3)
     describe "AnnotDetails Int" $
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> AnnotDetails Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (AnnotDetails Int))
     describe "Doc Int (annotated)" $
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> Annot.Doc Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Annot.Doc Int))
     describe "PrettyLevel (annotated)" $
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> Annot.PrettyLevel -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Annot.PrettyLevel)
     describe "Span Int" $
-        prop "TextShow instance"                 (prop_matchesTextShow :: Int -> Span Int -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy (Span Int))
 #endif
 
 -- | Verifies that the output of 'renderStyle' and 'renderStyleB' coincides.
diff --git a/tests/Spec/Text/XHtmlSpec.hs b/tests/Spec/Text/XHtmlSpec.hs
--- a/tests/Spec/Text/XHtmlSpec.hs
+++ b/tests/Spec/Text/XHtmlSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Text.XHtmlSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,12 +10,13 @@
 -}
 module Spec.Text.XHtmlSpec (main, spec) where
 
+import Data.Proxy (Proxy(..))
+
 import Instances.Text.XHtml ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.Text.XHtml ()
 import Text.XHtml.Frameset (Html, HtmlAttr, HotLink)
@@ -27,12 +28,12 @@
 spec :: Spec
 spec = parallel $ do
     describe "Html" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Html -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Html)
     describe "[Html]" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> [Html] -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy [Html])
     describe "HtmlAttr" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> HtmlAttr -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy HtmlAttr)
     describe "HotLink" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> HotLink -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy HotLink)
     describe "HtmlTable" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> HtmlTable -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy HtmlTable)
diff --git a/tests/Spec/Trace/HpcSpec.hs b/tests/Spec/Trace/HpcSpec.hs
--- a/tests/Spec/Trace/HpcSpec.hs
+++ b/tests/Spec/Trace/HpcSpec.hs
@@ -1,6 +1,6 @@
 {-|
 Module:      Spec.Trace.HpcSpec
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -10,12 +10,13 @@
 -}
 module Spec.Trace.HpcSpec (main, spec) where
 
+import Data.Proxy (Proxy(..))
+
 import Instances.Trace.Hpc ()
 
-import Spec.Utils (prop_matchesTextShow)
+import Spec.Utils (matchesTextShowSpec)
 
 import Test.Hspec (Spec, describe, hspec, parallel)
-import Test.Hspec.QuickCheck (prop)
 
 import TextShow.Trace.Hpc ()
 
@@ -29,16 +30,16 @@
 spec :: Spec
 spec = parallel $ do
     describe "Mix" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Mix -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Mix)
     describe "BoxLabel" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> BoxLabel -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy BoxLabel)
     describe "CondBox" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> CondBox -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy CondBox)
     describe "Tix" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Tix -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Tix)
     describe "TixModule" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> TixModule -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy TixModule)
     describe "HpcPos" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> HpcPos -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy HpcPos)
     describe "Hash" $
-        prop "TextShow instance" (prop_matchesTextShow :: Int -> Hash -> Bool)
+        matchesTextShowSpec (Proxy :: Proxy Hash)
diff --git a/tests/Spec/Utils.hs b/tests/Spec/Utils.hs
--- a/tests/Spec/Utils.hs
+++ b/tests/Spec/Utils.hs
@@ -1,9 +1,10 @@
-{-# LANGUAGE CPP              #-}
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 
 {-|
 Module:      Spec.Utils
-Copyright:   (C) 2014-2016 Ryan Scott
+Copyright:   (C) 2014-2017 Ryan Scott
 License:     BSD-style (see the file LICENSE)
 Maintainer:  Ryan Scott
 Stability:   Provisional
@@ -12,65 +13,90 @@
 Testing-related utility functions.
 -}
 module Spec.Utils (
-      ioProperty
-    , prop_matchesTextShow
-    , prop_matchesTextShow1
-#if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)
-    , prop_matchesTextShow2
+      matchesTextShowSpec
+    , matchesTextShow1Spec
+#if defined(NEW_FUNCTOR_CLASSES)
+    , matchesTextShow2Spec
 #endif
-    , prop_genericTextShow
-    , prop_genericTextShow1
+    , genericTextShowSpec
+    , genericTextShow1Spec
     ) where
 
-import           Data.Functor.Classes (Show1, showsPrec1)
+import Data.Functor.Classes (Show1, showsPrec1)
+import Data.Proxy (Proxy(..))
 
-import           Generics.Deriving.Base
+import Generics.Deriving.Base
 
-#if MIN_VERSION_QuickCheck(2,7,0)
-import qualified Test.QuickCheck as QC (ioProperty)
-#else
-import           Test.QuickCheck (morallyDubiousIOProperty)
-#endif
-import           Test.QuickCheck (Property, Testable)
+import Test.Hspec (Spec)
+import Test.Hspec.QuickCheck (prop)
+import Test.QuickCheck (Arbitrary)
 
-import           TextShow (TextShow(..), TextShow1(..), showbPrec1, fromString)
-import           TextShow.Generic
+import TextShow (TextShow(..), TextShow1(..), showbPrec1, fromString)
+import TextShow.Generic
 
-#if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)
-import           Data.Functor.Classes (Show2, showsPrec2)
-import           TextShow (TextShow2(..), showbPrec2)
+#if defined(NEW_FUNCTOR_CLASSES)
+import Data.Functor.Classes (Show2, showsPrec2)
+import TextShow (TextShow2(..), showbPrec2)
 #endif
 
-ioProperty :: Testable prop => IO prop -> Property
-#if MIN_VERSION_QuickCheck(2,7,0)
-ioProperty = QC.ioProperty
-#else
-ioProperty = morallyDubiousIOProperty
-#endif
+-- | Expect a type's 'Show' instances to coincide for both 'String's and 'Text',
+-- irrespective of precedence.
+matchesTextShowSpec :: forall a. (Arbitrary a, Show a, TextShow a)
+                    => Proxy a -> Spec
+matchesTextShowSpec _ = prop "TextShow instance" (prop_matchesTextShow :: Int -> a -> Bool)
 
--- | Verifies that a type's @Show@ instances coincide for both 'String's and 'Text',
+-- | Verifies that a type's 'Show' instances coincide for both 'String's and 'Text',
 -- irrespective of precedence.
 prop_matchesTextShow :: (Show a, TextShow a) => Int -> a -> Bool
 prop_matchesTextShow p x = fromString (showsPrec p x "") == showbPrec p x
 
--- | Verifies that a type's @Show1@ instances coincide for both 'String's and 'Text',
+-- | Expect a type's 'Show1' instances to coincide for both 'String's and 'Text',
 -- irrespective of precedence.
+matchesTextShow1Spec :: forall f a.
+                        (Arbitrary (f a), Show1 f, Show a, Show (f a), TextShow1 f, TextShow a)
+                     => Proxy (f a) -> Spec
+matchesTextShow1Spec _ = prop "TextShow1 instance" (prop_matchesTextShow1 :: Int -> f a -> Bool)
+
+-- | Verifies that a type's 'Show1' instances coincide for both 'String's and 'Text',
+-- irrespective of precedence.
 prop_matchesTextShow1 :: (Show1 f, Show a, TextShow1 f, TextShow a) => Int -> f a -> Bool
 prop_matchesTextShow1 p x = fromString (showsPrec1 p x "") == showbPrec1 p x
 
-#if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)
--- | Verifies that a type's @Show2@ instances coincide for both 'String's and 'Text',
+#if defined(NEW_FUNCTOR_CLASSES)
+-- | Expect a type's 'Show2' instances to coincide for both 'String's and 'Text',
 -- irrespective of precedence.
+matchesTextShow2Spec :: forall f a b.
+                        (Arbitrary (f a b), Show2 f, Show a, Show b, Show (f a b),
+                         TextShow2 f, TextShow a, TextShow b)
+                     => Proxy (f a b) -> Spec
+matchesTextShow2Spec _ = prop "TextShow2 instance" (prop_matchesTextShow2 :: Int -> f a b -> Bool)
+
+-- | Verifies that a type's 'Show2' instances coincide for both 'String's and 'Text',
+-- irrespective of precedence.
 prop_matchesTextShow2 :: (Show2 f, Show a, Show b, TextShow2 f, TextShow a, TextShow b)
                       => Int -> f a b -> Bool
 prop_matchesTextShow2 p x = fromString (showsPrec2 p x "") == showbPrec2 p x
 #endif
 
+-- | Expect a type's 'TextShow' instance to coincide with the output produced
+-- by the equivalent 'Generic' functions.
+genericTextShowSpec :: forall a. (Arbitrary a, Show a, TextShow a,
+                                  Generic a, GTextShowB Zero (Rep a))
+                    => Proxy a -> Spec
+genericTextShowSpec _ = prop "generic TextShow" (prop_genericTextShow  :: Int -> a -> Bool)
+
 -- | Verifies that a type's 'TextShow' instance coincides with the output produced
 -- by the equivalent 'Generic' functions.
 prop_genericTextShow :: (TextShow a, Generic a, GTextShowB Zero (Rep a))
                      => Int -> a -> Bool
 prop_genericTextShow p x = showbPrec p x == genericShowbPrec p x
+
+-- | Expect a type's 'TextShow1' instance to coincide with the output produced
+-- by the equivalent 'Generic1' functions.
+genericTextShow1Spec :: forall f a. (Arbitrary (f a), Show (f a), TextShow1 f,
+                                     Generic1 f, GTextShowB One (Rep1 f), TextShow a)
+                     => Proxy (f a) -> Spec
+genericTextShow1Spec _ = prop "generic TextShow1" (prop_genericTextShow1 :: Int -> f a -> Bool)
 
 -- | Verifies that a type's 'TextShow1' instance coincides with the output produced
 -- by the equivalent 'Generic1' functions.
diff --git a/text-show-instances.cabal b/text-show-instances.cabal
--- a/text-show-instances.cabal
+++ b/text-show-instances.cabal
@@ -1,5 +1,5 @@
 name:                text-show-instances
-version:             3.4
+version:             3.5
 synopsis:            Additional instances for text-show
 description:         @text-show-instances@ is a supplemental library to @text-show@
                      that provides additional @Show@ instances for data types in
@@ -15,7 +15,7 @@
                      .
                      * @<http://hackage.haskell.org/package/directory            directory>@
                      .
-                     * @<http://hackage.haskell.org/package/ghc-boot             ghc-boot>@
+                     * @<http://hackage.haskell.org/package/ghc-boot-th          ghc-boot-th>@
                      .
                      * @<http://hackage.haskell.org/package/haskeline            haskeline>@
                      .
@@ -62,7 +62,7 @@
 author:              Ryan Scott
 maintainer:          Ryan Scott <ryan.gl.scott@gmail.com>
 stability:           Experimental
-copyright:           (C) 2014-2016 Ryan Scott
+copyright:           (C) 2014-2017 Ryan Scott
 category:            Text
 build-type:          Simple
 tested-with:         GHC == 7.0.4
@@ -71,7 +71,7 @@
                    , GHC == 7.6.3
                    , GHC == 7.8.4
                    , GHC == 7.10.3
-                   , GHC == 8.0.1
+                   , GHC == 8.0.2
 extra-source-files:  CHANGELOG.md, README.md, include/inline.h
 cabal-version:       >=1.10
 
@@ -84,11 +84,21 @@
   default:             False
   manual:              True
 
-flag ghc-boot
-  description:         Depend on the ghc-boot package.
+flag base-4-9
+  description:         Use base-4.9 or later.
   default:             True
-  manual:              False
 
+flag template-haskell-2-11
+  description:         Use template-haskell-2.11.0.0 or later.
+  default:             True
+
+flag new-functor-classes
+  description:         Use a version of transformers or transformers-compat with a
+                       modern-style Data.Functor.Classes module. This flag cannot be
+                       used when building with transformers-0.4, since it comes with
+                       a different version of Data.Functor.Classes.
+  default: True
+
 library
   exposed-modules:     TextShow.Instances
 
@@ -113,9 +123,8 @@
                        TextShow.Text.XHtml
                        TextShow.Trace.Hpc
 
-                       -- Only exports functions if using ghc-boot
+                       -- Only exports functions if using ghc-boot-th
                        TextShow.GHC.LanguageExtensions.Type
-                       TextShow.GHC.PackageDb
 
                        -- Only exports functions if using Windows
                        TextShow.System.Win32
@@ -124,13 +133,12 @@
                        TextShow.System.Console.Terminfo
                        TextShow.System.Posix
   other-modules:       TextShow.Utils
-  build-depends:       base                 >= 4.3    && < 5
-                     , base-compat          >= 0.8.1  && < 1
-                     , bifunctors           >= 5.1    && < 6
+  build-depends:       base-compat          >= 0.8.1  && < 1
+                     , bifunctors           >= 5.2    && < 6
                      , binary               >= 0.6    && < 0.9
                      , bytestring           >= 0.9    && < 0.11
                      , containers           >= 0.1    && < 0.6
-                     , directory            >= 1      && < 1.3
+                     , directory            >= 1      && < 1.4
                      , haskeline            >= 0.7    && < 0.8
                      , hoopl                >= 3.8.7  && < 3.11
                      , hpc                  >= 0.5    && < 0.7
@@ -140,14 +148,11 @@
                      , random               >= 1.0.1  && < 1.2
                      , semigroups           >= 0.16.2 && < 1
                      , tagged               >= 0.4.4  && < 1
-                     , template-haskell     >= 2.5    && < 2.12
                      , text                 >= 0.11.1 && < 1.3
                      , text-show            >= 3.4    && < 4
                      , time                 >= 0.1    && < 1.7
-                     , transformers         >= 0.2.1  && < 0.6
-                     , transformers-compat  >= 0.5    && < 1
                      , unordered-containers >= 0.2    && < 0.3
-                     , vector               >= 0.9    && < 0.12
+                     , vector               >= 0.9    && < 0.13
                      , xhtml                >= 3000.2 && < 3000.3
   hs-source-dirs:      src
   default-language:    Haskell2010
@@ -156,9 +161,25 @@
   includes:            inline.h
   install-includes:    inline.h
 
-  if flag(ghc-boot)
-    build-depends:     ghc-boot
+  if flag(base-4-9)
+    build-depends:     base                >= 4.9 && < 5
+    cpp-options:       "-DNEW_FUNCTOR_CLASSES"
+  else
+    build-depends:     base                >= 4.3 && < 4.9
 
+  if flag(template-haskell-2-11)
+    build-depends:     template-haskell    >= 2.11 && < 2.13
+                     , ghc-boot-th         >= 8.0  && < 8.3
+  else
+    build-depends:     template-haskell    >= 2.5  && < 2.11
+
+  if flag(new-functor-classes)
+    build-depends:     transformers        (>= 0.2.1 && < 0.4) || (>= 0.5 && < 0.6)
+                     , transformers-compat >= 0.5 && < 1
+    cpp-options:       "-DNEW_FUNCTOR_CLASSES"
+  else
+    build-depends:     transformers == 0.4.*
+
   if os(windows)
     build-depends:     Win32                >= 2.1    && < 2.4
   else
@@ -186,10 +207,10 @@
                        Instances.Text.XHtml
                        Instances.Trace.Hpc
                        Instances.Utils
+                       Instances.Utils.GenericArbitrary
 
-                       -- Only defines instances if using ghc-boot
+                       -- Only defines instances if using ghc-boot-th
                        Instances.GHC.LanguageExtensions.Type
-                       Instances.GHC.PackageDb
 
                        -- Only defines instances if using Windows
                        Instances.System.Win32
@@ -219,9 +240,8 @@
                        Spec.Trace.HpcSpec
                        Spec.Utils
 
-                       -- Only defines tests if using ghc-boot
+                       -- Only defines tests if using ghc-boot-th
                        Spec.GHC.LanguageExtensions.TypeSpec
-                       Spec.GHC.PackageDbSpec
 
                        -- Only defines tests if using Windows
                        Spec.System.Win32Spec
@@ -229,13 +249,12 @@
                        -- Only defines tests if not using Windows
                        Spec.System.Console.TerminfoSpec
                        Spec.System.PosixSpec
-  build-depends:       base                 >= 4.3    && < 5
-                     , base-compat          >= 0.8.1  && < 1
-                     , bifunctors           >= 5.1    && < 6
+  build-depends:       base-compat          >= 0.8.1  && < 1
+                     , bifunctors           >= 5.2    && < 6
                      , binary               >= 0.6    && < 0.9
                      , bytestring           >= 0.9    && < 0.11
                      , containers           >= 0.1    && < 0.6
-                     , directory            >= 1      && < 1.3
+                     , directory            >= 1      && < 1.4
                      , generic-deriving     >= 1.9    && < 2
                      , ghc-prim
                      , haskeline            >= 0.7    && < 0.8
@@ -245,31 +264,44 @@
                      , old-locale           >= 1      && < 1.1
                      , old-time             >= 1      && < 1.2
                      , pretty               >= 1      && < 1.2
-                     , QuickCheck           >= 2.5    && < 3
+                     , QuickCheck           >= 2.9    && < 3
                      , quickcheck-instances >= 0.3.12 && < 0.4
                      , random               >= 1.0.1  && < 1.2
                      , semigroups           >= 0.17   && < 1
                      , tagged               >= 0.4.4  && < 1
-                     , template-haskell     >= 2.5    && < 2.12
                      , text                 >= 0.11.1 && < 1.3
                      , text-show            >= 3.4    && < 4
-                     , th-orphans           >= 0.13.2 && < 1
+                     , th-orphans           >= 0.13.3 && < 1
                      , time                 >= 0.1    && < 1.7
-                     , transformers         >= 0.2.1  && < 0.6
-                     , transformers-compat  >= 0.5    && < 1
                      , unordered-containers >= 0.2    && < 0.3
-                     , vector               >= 0.9    && < 0.12
+                     , vector               >= 0.9    && < 0.13
                      , xhtml                >= 3000.2 && < 3000.3
-  if !flag(developer)
-    build-depends:     text-show-instances  == 3.4
 
-  if flag(ghc-boot)
-    build-depends:     ghc-boot
+  if flag(base-4-9)
+    build-depends:     base                >= 4.9 && < 5
+    cpp-options:       "-DNEW_FUNCTOR_CLASSES"
+  else
+    build-depends:     base                >= 4.3 && < 4.9
 
-  hs-source-dirs:      tests
+  if flag(template-haskell-2-11)
+    build-depends:     template-haskell    >= 2.11 && < 2.13
+                     , ghc-boot-th         >= 8.0  && < 8.3
+  else
+    build-depends:     template-haskell    >= 2.5  && < 2.11
+
+  if flag(new-functor-classes)
+    build-depends:     transformers        (>= 0.2.1 && < 0.4) || (>= 0.5 && < 0.6)
+                     , transformers-compat >= 0.5 && < 1
+    cpp-options:       "-DNEW_FUNCTOR_CLASSES"
+  else
+    build-depends:     transformers        == 0.4.*
+
   if flag(developer)
     hs-source-dirs:    src
+  else
+    build-depends:     text-show-instances == 3.5
 
+  hs-source-dirs:      tests
   default-language:    Haskell2010
   ghc-options:         -Wall -threaded -rtsopts
   include-dirs:        include
