diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -4,6 +4,11 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/).
 
+## [0.5.0.0] - 2018-09-25
+### Change
+- When compiling with GHC 8.6 and newer, use `QuantifiedConstraints` instead
+  of `Eq1`, `Show1`, and `Arbitrary1`.
+
 ## [0.4.14.3] - 2018-09-21
 ### Change
 - Fix a CPP conditional import problem that caused build failures on GHC 7.10
diff --git a/quickcheck-classes.cabal b/quickcheck-classes.cabal
--- a/quickcheck-classes.cabal
+++ b/quickcheck-classes.cabal
@@ -1,5 +1,5 @@
 name: quickcheck-classes
-version: 0.4.14.3
+version: 0.5.0.0
 synopsis: QuickCheck common typeclasses
 description:
   This library provides QuickCheck properties to ensure
diff --git a/src/Test/QuickCheck/Classes/Alt.hs b/src/Test/QuickCheck/Classes/Alt.hs
--- a/src/Test/QuickCheck/Classes/Alt.hs
+++ b/src/Test/QuickCheck/Classes/Alt.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Alt
@@ -25,12 +29,15 @@
 #if MIN_VERSION_QuickCheck(2,10,0)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -43,16 +50,34 @@
 -- [/Left Distributivity/]
 --   @f '<$>' (a 'Alt.<!>' b) ≡ (f '<$>' a) 'Alt.<!>' (f '<$>' b)@
 #if defined(VERSION_semigroupoids)
-altLaws :: (Alt f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+altLaws :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Alt f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Alt f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 altLaws p = Laws "Alt"
   [ ("Associativity", altAssociative p)
   , ("Left Distributivity", altLeftDistributive p)
   ]
 
-altAssociative :: forall proxy f. (Alt f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+altAssociative :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Alt f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Alt f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 altAssociative _ = property $ \(Apply (a :: f Integer)) (Apply (b :: f Integer)) (Apply (c :: f Integer)) -> eq1 ((a Alt.<!> b) Alt.<!> c) (a Alt.<!> (b Alt.<!> c))
 
-altLeftDistributive :: forall proxy f. (Alt f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+altLeftDistributive :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Alt f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Alt f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 altLeftDistributive _ = property $ \(Apply (a :: f Integer)) (Apply (b :: f Integer)) -> eq1 (id <$> (a Alt.<!> b)) ((id <$> a) Alt.<!> (id <$> b))
 #endif
 #endif
diff --git a/src/Test/QuickCheck/Classes/Alternative.hs b/src/Test/QuickCheck/Classes/Alternative.hs
--- a/src/Test/QuickCheck/Classes/Alternative.hs
+++ b/src/Test/QuickCheck/Classes/Alternative.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Alternative
@@ -17,12 +21,15 @@
 #if MIN_VERSION_QuickCheck(2,10,0)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -36,20 +43,44 @@
 --   @x '<|>' 'empty' ≡ x@
 -- [/Associativity/]
 --   @a '<|>' (b '<|>' c) ≡ (a '<|>' b) '<|>' c)@
-alternativeLaws :: (Alternative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+alternativeLaws ::
+#if MIN_VERSION_base(4,12,0)
+  (Alternative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Alternative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 alternativeLaws p = Laws "Alternative"
   [ ("Left Identity", alternativeLeftIdentity p)
   , ("Right Identity", alternativeRightIdentity p)
   , ("Associativity", alternativeAssociativity p)
   ]
 
-alternativeLeftIdentity :: forall proxy f. (Alternative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+alternativeLeftIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Alternative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Alternative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 alternativeLeftIdentity _ = property $ \(Apply (a :: f Integer)) -> (eq1 (empty <|> a) a)
 
-alternativeRightIdentity :: forall proxy f. (Alternative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+alternativeRightIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Alternative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Alternative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 alternativeRightIdentity _ = property $ \(Apply (a :: f Integer)) -> (eq1 a (empty <|> a))
 
-alternativeAssociativity :: forall proxy f. (Alternative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+alternativeAssociativity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Alternative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Alternative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 alternativeAssociativity _ = property $ \(Apply (a :: f Integer)) (Apply (b :: f Integer)) (Apply (c :: f Integer)) -> eq1 (a <|> (b <|> c)) ((a <|> b) <|> c)
 
 #endif
diff --git a/src/Test/QuickCheck/Classes/Applicative.hs b/src/Test/QuickCheck/Classes/Applicative.hs
--- a/src/Test/QuickCheck/Classes/Applicative.hs
+++ b/src/Test/QuickCheck/Classes/Applicative.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Applicative
@@ -17,12 +21,15 @@
 #if MIN_VERSION_QuickCheck(2,10,0)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -40,7 +47,13 @@
 --   @u '<*>' 'pure' y ≡ 'pure' ('$' y) '<*>' u@
 -- [/LiftA2 (1)/]
 --   @('<*>') ≡ 'liftA2' 'id'@
-applicativeLaws :: (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+applicativeLaws ::
+#if MIN_VERSION_base(4,12,0)
+  (Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 applicativeLaws p = Laws "Applicative"
   [ ("Identity", applicativeIdentity p)
   , ("Composition", applicativeComposition p)
@@ -50,26 +63,56 @@
     -- todo: liftA2 part 2, we need an equation of two variables for this
   ]
 
-applicativeIdentity :: forall proxy f. (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+applicativeIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 applicativeIdentity _ = property $ \(Apply (a :: f Integer)) -> eq1 (pure id <*> a) a
 
-applicativeComposition :: forall proxy f. (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+applicativeComposition :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 applicativeComposition _ = property $ \(Apply (u' :: f QuadraticEquation)) (Apply (v' :: f QuadraticEquation)) (Apply (w :: f Integer)) ->
   let u = fmap runQuadraticEquation u'
       v = fmap runQuadraticEquation v'
    in eq1 (pure (.) <*> u <*> v <*> w) (u <*> (v <*> w))
 
-applicativeHomomorphism :: forall proxy f. (Applicative f, Eq1 f, Show1 f) => proxy f -> Property
+applicativeHomomorphism :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a))
+#else
+  (Applicative f, Eq1 f, Show1 f)
+#endif
+  => proxy f -> Property
 applicativeHomomorphism _ = property $ \(e :: QuadraticEquation) (a :: Integer) ->
   let f = runQuadraticEquation e
    in eq1 (pure f <*> pure a) (pure (f a) :: f Integer)
 
-applicativeInterchange :: forall proxy f. (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+applicativeInterchange :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 applicativeInterchange _ = property $ \(Apply (u' :: f QuadraticEquation)) (y :: Integer) ->
   let u = fmap runQuadraticEquation u'
    in eq1 (u <*> pure y) (pure ($ y) <*> u)
 
-applicativeLiftA2_1 :: forall proxy f. (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+applicativeLiftA2_1 :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 applicativeLiftA2_1 _ = property $ \(Apply (f' :: f QuadraticEquation)) (Apply (x :: f Integer)) ->
   let f = fmap runQuadraticEquation f'
    in eq1 (liftA2 id f x) (f <*> x)
diff --git a/src/Test/QuickCheck/Classes/Apply.hs b/src/Test/QuickCheck/Classes/Apply.hs
--- a/src/Test/QuickCheck/Classes/Apply.hs
+++ b/src/Test/QuickCheck/Classes/Apply.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Apply
@@ -24,12 +28,15 @@
 #if MIN_VERSION_QuickCheck(2,10,0)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -40,12 +47,24 @@
 -- [/LiftF2 (1)/]
 --   @('FunctorApply.<.>') ≡ 'liftF2' 'id'@
 #if defined(VERSION_semigroupoids)
-applyLaws :: (FunctorApply.Apply f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+applyLaws ::
+#if MIN_VERSION_base(4,12,0)
+  (FunctorApply.Apply f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (FunctorApply.Apply f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 applyLaws p = Laws "Apply"
   [ ("LiftF2 part 1", applyLiftF2_1 p)
   ]
 
-applyLiftF2_1 :: forall proxy f. (FunctorApply.Apply f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+applyLiftF2_1 :: forall proxy f. 
+#if MIN_VERSION_base(4,12,0)
+  (FunctorApply.Apply f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (FunctorApply.Apply f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 applyLiftF2_1 _ = property $ \(Apply (f' :: f QuadraticEquation)) (Apply (x :: f Integer)) ->
   let f = fmap runQuadraticEquation f'
   in eq1 (FunctorApply.liftF2 id f x) (f FunctorApply.<.> x)
diff --git a/src/Test/QuickCheck/Classes/Bifunctor.hs b/src/Test/QuickCheck/Classes/Bifunctor.hs
--- a/src/Test/QuickCheck/Classes/Bifunctor.hs
+++ b/src/Test/QuickCheck/Classes/Bifunctor.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Bifunctor
@@ -14,12 +18,15 @@
 
 import Data.Bifunctor(Bifunctor(..))
 import Test.QuickCheck hiding ((.&.))
-#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
+import Data.Functor.Classes (Eq2,Show2)
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
+import Test.QuickCheck.Classes.Compat (eq2)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -38,7 +45,13 @@
 --
 -- /Note/: This property test is only available when this package is built with
 -- @base-4.9+@ or @transformers-0.5+@.
-bifunctorLaws :: (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f) => proxy f -> Laws
+bifunctorLaws :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Bifunctor f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
+#else
+  (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f)
+#endif
+  => proxy f -> Laws
 bifunctorLaws p = Laws "Bifunctor"
   [ ("Identity", bifunctorIdentity p)
   , ("First Identity", bifunctorFirstIdentity p)
@@ -46,18 +59,39 @@
   , ("Bifunctor Composition", bifunctorComposition p)
   ]
 
-bifunctorIdentity :: forall proxy f. (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f) => proxy f -> Property
+bifunctorIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Bifunctor f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
+#else
+  (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f)
+#endif
+  => proxy f -> Property
 bifunctorIdentity _ = property $ \(Apply2 (x :: f Integer Integer)) -> eq2 (bimap id id x) x
 
-bifunctorFirstIdentity :: forall proxy f. (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f) => proxy f -> Property
+bifunctorFirstIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Bifunctor f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
+#else
+  (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f)
+#endif
+  => proxy f -> Property
 bifunctorFirstIdentity _ = property $ \(Apply2 (x :: f Integer Integer)) -> eq2 (first id x) x
 
-bifunctorSecondIdentity :: forall proxy f. (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f) => proxy f -> Property
+bifunctorSecondIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Bifunctor f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
+#else
+  (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f)
+#endif
+  => proxy f -> Property
 bifunctorSecondIdentity _ = property $ \(Apply2 (x :: f Integer Integer)) -> eq2 (second id x) x
 
-bifunctorComposition
-  :: forall proxy f.
-     (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f)
+bifunctorComposition :: forall proxy f. 
+#if MIN_VERSION_base(4,12,0)
+  (Bifunctor f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
+#else
+  (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f)
+#endif
   => proxy f -> Property
 bifunctorComposition _ = property $ \(Apply2 (z :: f Integer Integer)) -> eq2 (bimap id id z) ((first id . second id) z)
 #endif
diff --git a/src/Test/QuickCheck/Classes/Category.hs b/src/Test/QuickCheck/Classes/Category.hs
--- a/src/Test/QuickCheck/Classes/Category.hs
+++ b/src/Test/QuickCheck/Classes/Category.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Category
@@ -16,12 +20,15 @@
 import Prelude hiding (id, (.))
 import Control.Category (Category(..))
 import Test.QuickCheck hiding ((.&.))
-#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
+import Data.Functor.Classes (Eq2,Show2)
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
+import Test.QuickCheck.Classes.Compat (eq2)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -38,7 +45,13 @@
 --
 -- /Note/: This property test is only available when this package is built with
 -- @base-4.9+@ or @transformers-0.5+@.
-categoryLaws :: (Category cat, Eq2 cat, Show2 cat, Arbitrary2 cat) => proxy cat -> Laws
+categoryLaws :: forall proxy c.
+#if MIN_VERSION_base(4,12,0)
+  (Category c, forall a b. (Eq a, Eq b) => Eq (c a b), forall a b. (Show a, Show b) => Show (c a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (c a b))
+#else
+  (Category c, Eq2 c, Show2 c, Arbitrary2 c)
+#endif
+  => proxy c -> Laws
 categoryLaws p = Laws "Category"
   [ ("Right Identity", categoryRightIdentity p)
   , ("Left Identity", categoryLeftIdentity p)
@@ -52,22 +65,52 @@
 --
 -- /Note/: This property test is only available when this package is built with
 -- @base-4.9+@ or @transformers-0.5+@.
-commutativeCategoryLaws :: (Category cat, Eq2 cat, Show2 cat, Arbitrary2 cat) => proxy cat -> Laws
+commutativeCategoryLaws :: forall proxy c.
+#if MIN_VERSION_base(4,12,0)
+  (Category c, forall a b. (Eq a, Eq b) => Eq (c a b), forall a b. (Show a, Show b) => Show (c a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (c a b))
+#else
+  (Category c, Eq2 c, Show2 c, Arbitrary2 c)
+#endif
+  => proxy c -> Laws
 commutativeCategoryLaws p = Laws "Commutative Category" $ lawsProperties (categoryLaws p) ++
   [ ("Commutative", categoryCommutativity p)
   ]
 
-categoryRightIdentity :: forall proxy cat. (Category cat, Eq2 cat, Show2 cat, Arbitrary2 cat) => proxy cat -> Property
-categoryRightIdentity _ = property $ \(Apply2 (x :: cat Integer Integer)) -> eq2 (x . id) x
+categoryRightIdentity :: forall proxy c.
+#if MIN_VERSION_base(4,12,0)
+  (Category c, forall a b. (Eq a, Eq b) => Eq (c a b), forall a b. (Show a, Show b) => Show (c a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (c a b))
+#else
+  (Category c, Eq2 c, Show2 c, Arbitrary2 c)
+#endif
+  => proxy c -> Property
+categoryRightIdentity _ = property $ \(Apply2 (x :: c Integer Integer)) -> eq2 (x . id) x
 
-categoryLeftIdentity :: forall proxy cat. (Category cat, Eq2 cat, Show2 cat, Arbitrary2 cat) => proxy cat -> Property
-categoryLeftIdentity _ = property $ \(Apply2 (x :: cat Integer Integer)) -> eq2 (id . x) x
+categoryLeftIdentity :: forall proxy c.
+#if MIN_VERSION_base(4,12,0)
+  (Category c, forall a b. (Eq a, Eq b) => Eq (c a b), forall a b. (Show a, Show b) => Show (c a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (c a b))
+#else
+  (Category c, Eq2 c, Show2 c, Arbitrary2 c)
+#endif
+  => proxy c -> Property
+categoryLeftIdentity _ = property $ \(Apply2 (x :: c Integer Integer)) -> eq2 (id . x) x
 
-categoryAssociativity :: forall proxy cat. (Category cat, Eq2 cat, Show2 cat, Arbitrary2 cat) => proxy cat -> Property
-categoryAssociativity _ = property $ \(Apply2 (f :: cat Integer Integer)) (Apply2 (g :: cat Integer Integer)) (Apply2 (h :: cat Integer Integer)) -> eq2 (f . (g . h)) ((f . g) . h)
+categoryAssociativity :: forall proxy c.
+#if MIN_VERSION_base(4,12,0)
+  (Category c, forall a b. (Eq a, Eq b) => Eq (c a b), forall a b. (Show a, Show b) => Show (c a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (c a b))
+#else
+  (Category c, Eq2 c, Show2 c, Arbitrary2 c)
+#endif
+  => proxy c -> Property
+categoryAssociativity _ = property $ \(Apply2 (f :: c Integer Integer)) (Apply2 (g :: c Integer Integer)) (Apply2 (h :: c Integer Integer)) -> eq2 (f . (g . h)) ((f . g) . h)
 
-categoryCommutativity :: forall proxy cat. (Category cat, Eq2 cat, Show2 cat, Arbitrary2 cat) => proxy cat -> Property
-categoryCommutativity _ = property $ \(Apply2 (f :: cat Integer Integer)) (Apply2 (g :: cat Integer Integer)) -> eq2 (f . g) (g . f)
+categoryCommutativity :: forall proxy c.
+#if MIN_VERSION_base(4,12,0)
+  (Category c, forall a b. (Eq a, Eq b) => Eq (c a b), forall a b. (Show a, Show b) => Show (c a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (c a b))
+#else
+  (Category c, Eq2 c, Show2 c, Arbitrary2 c)
+#endif
+  => proxy c -> Property
+categoryCommutativity _ = property $ \(Apply2 (f :: c Integer Integer)) (Apply2 (g :: c Integer Integer)) -> eq2 (f . g) (g . f)
 
 #endif
 
diff --git a/src/Test/QuickCheck/Classes/Common.hs b/src/Test/QuickCheck/Classes/Common.hs
--- a/src/Test/QuickCheck/Classes/Common.hs
+++ b/src/Test/QuickCheck/Classes/Common.hs
@@ -1,5 +1,12 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE UndecidableInstances #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Common
@@ -102,12 +109,23 @@
 
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
 -- the Functor constraint is needed for transformers-0.4
+#if MIN_VERSION_base(4,12,0)
+nestedEq1 :: (forall x. Eq x => Eq (f x), forall x. Eq x => Eq (g x), Eq a) => f (g a) -> f (g a) -> Bool
+nestedEq1 = (==)
+#else
 nestedEq1 :: (Eq1 f, Eq1 g, Eq a, Functor f) => f (g a) -> f (g a) -> Bool
 nestedEq1 x y = eq1 (Compose x) (Compose y)
+#endif
 
+#if MIN_VERSION_base(4,12,0)
+propNestedEq1 :: (forall x. Eq x => Eq (f x), forall x. Eq x => Eq (g x), Eq a, forall x. Show x => Show (f x), forall x. Show x => Show (g x), Show a)
+  => f (g a) -> f (g a) -> Property
+propNestedEq1 = (===)
+#else
 propNestedEq1 :: (Eq1 f, Eq1 g, Eq a, Show1 f, Show1 g, Show a, Functor f)
   => f (g a) -> f (g a) -> Property
 propNestedEq1 x y = Compose x === Compose y
+#endif
 
 toSpecialApplicative ::
      Compose Triple ((,) (S.Set Integer)) Integer
@@ -269,6 +287,11 @@
   mempty = Apply $ pure mempty
   mappend = (SG.<>)
 
+#if MIN_VERSION_base(4,12,0)
+deriving instance (forall x. Eq x => Eq (f x), Eq a) => Eq (Apply f a)
+deriving instance (forall x. Arbitrary x => Arbitrary (f x), Arbitrary a) => Arbitrary (Apply f a)
+deriving instance (forall x. Show x => Show (f x), Show a) => Show (Apply f a)
+#else
 #if MIN_VERSION_base(4,8,0) || MIN_VERSION_transformers(0,5,0)
 instance (Eq1 f, Eq a) => Eq (Apply f a) where
   Apply a == Apply b = eq1 a b
@@ -285,6 +308,7 @@
   shrink = map Apply . shrink1 . getApply
 #endif
 #endif
+#endif
 
 foldMapA :: (Foldable t, Monoid m, Semigroup m, Applicative f) => (a -> f m) -> t a -> f m
 foldMapA f = getApply . foldMap (Apply . f)
@@ -293,6 +317,11 @@
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
 newtype Apply2 f a b = Apply2 { getApply2 :: f a b }
 
+#if MIN_VERSION_base(4,12,0)
+deriving instance (forall x y. (Eq x, Eq y) => Eq (f x y), Eq a, Eq b) => Eq (Apply2 f a b)
+deriving instance (forall x y. (Arbitrary x, Arbitrary y) => Arbitrary (f x y), Arbitrary a, Arbitrary b) => Arbitrary (Apply2 f a b)
+deriving instance (forall x y. (Show x, Show y) => Show (f x y), Show a, Show b) => Show (Apply2 f a b)
+#else
 instance (Eq2 f, Eq a, Eq b) => Eq (Apply2 f a b) where
   Apply2 a == Apply2 b = eq2 a b
 
@@ -305,6 +334,7 @@
   shrink = fmap Apply2 . shrink2 . getApply2
 #endif
 #endif
+#endif
 
 data LinearEquation = LinearEquation
   { _linearEquationLinear :: Integer
@@ -335,6 +365,21 @@
   then liftM (flip runLinearEquation i) e1
   else liftM (flip runLinearEquation i) e2
 
+#if MIN_VERSION_base(4,12,0)
+deriving instance (forall x. Eq x => Eq (m x)) => Eq (LinearEquationM m)
+instance (forall a. Show a => Show (m a)) => Show (LinearEquationM m) where
+  show (LinearEquationM a b) = (\f -> f "")
+    $ showString "\\x -> if odd x then "
+    . showsPrec 0 a
+    . showString " else "
+    . showsPrec 0 b
+instance (forall a. Arbitrary a => Arbitrary (m a)) => Arbitrary (LinearEquationM m) where
+  arbitrary = liftA2 LinearEquationM arbitrary arbitrary
+  shrink (LinearEquationM a b) = L.concat
+    [ map (\x -> LinearEquationM x b) (shrink a)
+    , map (\x -> LinearEquationM a x) (shrink b)
+    ]
+#else
 instance Eq1 m => Eq (LinearEquationM m) where
   LinearEquationM a1 b1 == LinearEquationM a2 b2 = eq1 a1 a2 && eq1 b1 b2
 
@@ -352,6 +397,7 @@
     [ map (\x -> LinearEquationM x b) (shrink1 a)
     , map (\x -> LinearEquationM a x) (shrink1 b)
     ]
+#endif
 #endif
 #endif
 
diff --git a/src/Test/QuickCheck/Classes/Compat.hs b/src/Test/QuickCheck/Classes/Compat.hs
--- a/src/Test/QuickCheck/Classes/Compat.hs
+++ b/src/Test/QuickCheck/Classes/Compat.hs
@@ -1,15 +1,50 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE MagicHash #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 module Test.QuickCheck.Classes.Compat
   ( isTrue#
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+  , eq1
+#endif
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
+  , eq2
+#endif
   ) where
 
 #if MIN_VERSION_base(4,7,0)
 import GHC.Exts (isTrue#)
 #endif
 
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import qualified Data.Functor.Classes as C
+#endif
+
 #if !MIN_VERSION_base(4,7,0)
 isTrue# :: Bool -> Bool
 isTrue# b = b
 #endif
+
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+#if MIN_VERSION_base(4,12,0)
+eq1 :: (forall a. Eq a => Eq (f a), Eq a) => f a -> f a -> Bool
+eq1 = (==)
+#else
+eq1 :: (C.Eq1 f, Eq a) => f a -> f a -> Bool
+eq1 = C.eq1
+#endif
+#endif
+
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
+#if MIN_VERSION_base(4,12,0)
+eq2 :: (forall a. (Eq a, Eq b) => Eq (f a b), Eq a, Eq b) => f a b -> f a b -> Bool
+eq2 = (==)
+#else
+eq2 :: (C.Eq2 f, Eq a, Eq b) => f a b -> f a b -> Bool
+eq2 = C.eq2
+#endif
+#endif
+
diff --git a/src/Test/QuickCheck/Classes/Foldable.hs b/src/Test/QuickCheck/Classes/Foldable.hs
--- a/src/Test/QuickCheck/Classes/Foldable.hs
+++ b/src/Test/QuickCheck/Classes/Foldable.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Foldable
@@ -21,7 +25,7 @@
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 import Test.QuickCheck.Monadic (monadicIO)
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
@@ -30,6 +34,9 @@
 import qualified Data.Semigroup as SG
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -62,10 +69,22 @@
 --
 -- Note that this checks to ensure that @foldl\'@ and @foldr\'@
 -- are suitably strict.
-foldableLaws :: (Foldable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+foldableLaws :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Foldable f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Foldable f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 foldableLaws = foldableLawsInternal
 
-foldableLawsInternal :: forall proxy f. (Foldable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+foldableLawsInternal :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Foldable f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Foldable f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 foldableLawsInternal p = Laws "Foldable"
   [ (,) "fold" $ property $ \(Apply (a :: f (SG.Sum Integer))) ->
       F.fold a == F.foldMap id a
@@ -110,7 +129,13 @@
 compatToList :: Foldable f => f a -> [a]
 compatToList = foldMap (\x -> [x])
 
-foldableFoldl' :: forall proxy f. (Foldable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+foldableFoldl' :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Foldable f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Foldable f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 foldableFoldl' _ = property $ \(_ :: ChooseSecond) (_ :: LastNothing) (Apply (xs :: f (Bottom Integer))) ->
   monadicIO $ do
     let f :: Integer -> Bottom Integer -> Integer
@@ -133,7 +158,13 @@
         Right i -> return (Just i)
     return (r1 == r2)
 
-foldableFoldr' :: forall proxy f. (Foldable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+foldableFoldr' :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Foldable f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Foldable f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 foldableFoldr' _ = property $ \(_ :: ChooseFirst) (_ :: LastNothing) (Apply (xs :: f (Bottom Integer))) ->
   monadicIO $ do
     let f :: Bottom Integer -> Integer -> Integer
diff --git a/src/Test/QuickCheck/Classes/Functor.hs b/src/Test/QuickCheck/Classes/Functor.hs
--- a/src/Test/QuickCheck/Classes/Functor.hs
+++ b/src/Test/QuickCheck/Classes/Functor.hs
@@ -1,6 +1,12 @@
+{-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Functor
@@ -17,12 +23,15 @@
 #if MIN_VERSION_QuickCheck(2,10,0)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -36,21 +45,46 @@
 --   @'fmap' (f '.' g) ≡ 'fmap' f '.' 'fmap' g@
 -- [/Const/]
 --   @('<$') ≡ 'fmap' 'const'@
-functorLaws :: (Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+functorLaws ::
+#if MIN_VERSION_base(4,12,0)
+  (Functor f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Functor f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f
+  -> Laws
 functorLaws p = Laws "Functor"
   [ ("Identity", functorIdentity p)
   , ("Composition", functorComposition p)
   , ("Const", functorConst p)
   ]
 
-functorIdentity :: forall proxy f. (Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+functorIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Functor f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Functor f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 functorIdentity _ = property $ \(Apply (a :: f Integer)) -> eq1 (fmap id a) a
 
-functorComposition :: forall proxy f. (Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+functorComposition :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Functor f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Functor f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 functorComposition _ = property $ \(Apply (a :: f Integer)) ->
   eq1 (fmap func2 (fmap func1 a)) (fmap (func2 . func1) a)
 
-functorConst :: forall proxy f. (Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+functorConst :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Functor f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Functor f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 functorConst _ = property $ \(Apply (a :: f Integer)) ->
   eq1 (fmap (const 'X') a) ('X' <$ a)
 
diff --git a/src/Test/QuickCheck/Classes/Monad.hs b/src/Test/QuickCheck/Classes/Monad.hs
--- a/src/Test/QuickCheck/Classes/Monad.hs
+++ b/src/Test/QuickCheck/Classes/Monad.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Monad
@@ -18,12 +22,15 @@
 import Control.Monad (ap)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -41,7 +48,13 @@
 --   @'pure' ≡ 'return'@
 -- [/Ap/]
 --   @('<*>') ≡ 'ap'@
-monadLaws :: (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+monadLaws ::
+#if MIN_VERSION_base(4,12,0)
+  (Monad f, Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 monadLaws p = Laws "Monad"
   [ ("Left Identity", monadLeftIdentity p)
   , ("Right Identity", monadRightIdentity p)
@@ -50,26 +63,56 @@
   , ("Ap", monadAp p)
   ]
 
-monadLeftIdentity :: forall proxy f. (Monad f, Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadLeftIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Monad f, Functor f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Monad f, Functor f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadLeftIdentity _ = property $ \(k' :: LinearEquationM f) (a :: Integer) ->
   let k = runLinearEquationM k'
    in eq1 (return a >>= k) (k a)
 
-monadRightIdentity :: forall proxy f. (Monad f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadRightIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Monad f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Monad f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadRightIdentity _ = property $ \(Apply (m :: f Integer)) ->
   eq1 (m >>= return) m
 
-monadAssociativity :: forall proxy f. (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadAssociativity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Monad f, Functor f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Monad f, Functor f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadAssociativity _ = property $ \(Apply (m :: f Integer)) (k' :: LinearEquationM f) (h' :: LinearEquationM f) ->
   let k = runLinearEquationM k'
       h = runLinearEquationM h'
    in eq1 (m >>= (\x -> k x >>= h)) ((m >>= k) >>= h)
 
-monadReturn :: forall proxy f. (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadReturn :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Monad f, Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadReturn _ = property $ \(x :: Integer) ->
   eq1 (return x) (pure x :: f Integer)
 
-monadAp :: forall proxy f. (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadAp :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Monad f, Applicative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadAp _ = property $ \(Apply (f' :: f QuadraticEquation)) (Apply (x :: f Integer)) ->
   let f = fmap runQuadraticEquation f'
    in eq1 (ap f x) (f <*> x)
diff --git a/src/Test/QuickCheck/Classes/MonadFail.hs b/src/Test/QuickCheck/Classes/MonadFail.hs
--- a/src/Test/QuickCheck/Classes/MonadFail.hs
+++ b/src/Test/QuickCheck/Classes/MonadFail.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.MonadFail
@@ -18,7 +22,7 @@
 import Control.Monad (ap)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) && MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 import Prelude hiding (fail)
 import Control.Monad.Fail (MonadFail(..))
 #endif
@@ -26,6 +30,9 @@
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -35,12 +42,24 @@
 -- 
 -- [/Left Zero/]
 -- @'fail' s '>>=' f ≡ 'fail' s@
-monadFailLaws :: (MonadFail f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+monadFailLaws :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (MonadFail f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadFail f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 monadFailLaws p = Laws "Monad"
   [ ("Left Zero", monadFailLeftZero p)
   ]
  
-monadFailLeftZero :: forall proxy f. (MonadFail f, Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadFailLeftZero :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (MonadFail f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadFail f, Functor f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadFailLeftZero _ = property $ \(k' :: LinearEquationM f) (s :: String) ->
   let k = runLinearEquationM k'
   in eq1 (fail s >>= k) (fail s)
diff --git a/src/Test/QuickCheck/Classes/MonadPlus.hs b/src/Test/QuickCheck/Classes/MonadPlus.hs
--- a/src/Test/QuickCheck/Classes/MonadPlus.hs
+++ b/src/Test/QuickCheck/Classes/MonadPlus.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.MonadPlus
@@ -15,13 +19,16 @@
 import Test.QuickCheck hiding ((.&.))
 import Test.QuickCheck.Property (Property)
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 import Control.Applicative(Alternative(empty))
 import Control.Monad (MonadPlus(mzero,mplus))
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,8,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 
@@ -40,7 +47,13 @@
 --   @'mzero' '>>=' f ≡ 'mzero'@
 -- [/Right Zero/]
 --   @m '>>' 'mzero' ≡ 'mzero'@
-monadPlusLaws :: (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+monadPlusLaws ::
+#if MIN_VERSION_base(4,12,0)
+  (MonadPlus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 monadPlusLaws p = Laws "MonadPlus"
   [ ("Left Identity", monadPlusLeftIdentity p)
   , ("Right Identity", monadPlusRightIdentity p)
@@ -49,19 +62,49 @@
   , ("Right Zero", monadPlusRightZero p)
   ]
 
-monadPlusLeftIdentity :: forall proxy f. (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadPlusLeftIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (MonadPlus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadPlusLeftIdentity _ = property $ \(Apply (a :: f Integer)) -> eq1 (mplus mzero a) a
 
-monadPlusRightIdentity :: forall proxy f. (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadPlusRightIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (MonadPlus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadPlusRightIdentity _ = property $ \(Apply (a :: f Integer)) -> eq1 (mplus a mzero) a
 
-monadPlusAssociativity :: forall proxy f. (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadPlusAssociativity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (MonadPlus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadPlusAssociativity _ = property $ \(Apply (a :: f Integer)) (Apply (b :: f Integer)) (Apply (c :: f Integer)) -> eq1 (mplus a (mplus b c)) (mplus (mplus a b) c)
 
-monadPlusLeftZero :: forall proxy f. (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadPlusLeftZero :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (MonadPlus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadPlusLeftZero _ = property $ \(k' :: LinearEquationM f) -> eq1 (mzero >>= runLinearEquationM k') mzero
 
-monadPlusRightZero :: forall proxy f. (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadPlusRightZero :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (MonadPlus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadPlusRightZero _ = property $ \(Apply (a :: f Integer)) -> eq1 (a >> (mzero :: f Integer)) mzero
 
 #endif
diff --git a/src/Test/QuickCheck/Classes/MonadZip.hs b/src/Test/QuickCheck/Classes/MonadZip.hs
--- a/src/Test/QuickCheck/Classes/MonadZip.hs
+++ b/src/Test/QuickCheck/Classes/MonadZip.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.MonadZip
@@ -20,12 +24,15 @@
 import Control.Monad (liftM)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -38,12 +45,24 @@
 --
 -- In the laws above, the infix function @'***'@ refers to a typeclass
 -- method of 'Arrow'.
-monadZipLaws :: (MonadZip f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+monadZipLaws ::
+#if MIN_VERSION_base(4,12,0)
+  (MonadZip f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadZip f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 monadZipLaws p = Laws "MonadZip"
   [ ("Naturality", monadZipNaturality p)
   ]
 
-monadZipNaturality :: forall proxy f. (MonadZip f, Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+monadZipNaturality :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (MonadZip f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (MonadZip f, Functor f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 monadZipNaturality _ = property $ \(f' :: LinearEquation) (g' :: LinearEquation) (Apply (ma :: f Integer)) (Apply (mb :: f Integer)) ->
   let f = runLinearEquation f'
       g = runLinearEquation g'
diff --git a/src/Test/QuickCheck/Classes/Plus.hs b/src/Test/QuickCheck/Classes/Plus.hs
--- a/src/Test/QuickCheck/Classes/Plus.hs
+++ b/src/Test/QuickCheck/Classes/Plus.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Plus
@@ -28,13 +32,16 @@
 #if MIN_VERSION_QuickCheck(2,10,0)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 import qualified Control.Applicative as Alternative
 #endif
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -47,7 +54,13 @@
 -- [/Right Identity/]
 --   @m 'Alt.<!>' 'Plus.zero' ≡ m@
 #if defined(VERSION_semigroupoids)
-plusLaws :: (Plus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+plusLaws :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Plus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Plus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 plusLaws p = Laws "Plus"
   [ ("Left Identity", plusLeftIdentity p)
   , ("Right Identity", plusRightIdentity p)
@@ -57,18 +70,42 @@
 --
 -- [/Congruency/]
 --   @'Plus.zero' ≡ 'Alternative.empty'@
-extendedPlusLaws :: (Plus f, Alternative.Alternative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+extendedPlusLaws :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Plus f, Alternative.Alternative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Plus f, Alternative.Alternative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 extendedPlusLaws p = Laws "Plus extended to Alternative" $ lawsProperties (plusLaws p) ++
   [ ("Congruency", extendedPlusLaw p)
   ]
 
-extendedPlusLaw :: forall proxy f. (Plus f, Alternative.Alternative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+extendedPlusLaw :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Plus f, Alternative.Alternative f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Plus f, Alternative.Alternative f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 extendedPlusLaw _ = property $ eq1 (Plus.zero :: f Integer) (Alternative.empty :: f Integer)
 
-plusLeftIdentity :: forall proxy f. (Plus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+plusLeftIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Plus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Plus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 plusLeftIdentity _ = property $ \(Apply (m :: f Integer)) -> eq1 (Plus.zero Alt.<!> m) m
 
-plusRightIdentity :: forall proxy f. (Plus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Property
+plusRightIdentity :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Plus f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Plus f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Property
 plusRightIdentity _ = property $ \(Apply (m :: f Integer)) -> eq1 (m Alt.<!> Plus.zero) m
 
 #endif
diff --git a/src/Test/QuickCheck/Classes/Semigroupoid.hs b/src/Test/QuickCheck/Classes/Semigroupoid.hs
--- a/src/Test/QuickCheck/Classes/Semigroupoid.hs
+++ b/src/Test/QuickCheck/Classes/Semigroupoid.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Semigroupoid
@@ -20,12 +24,15 @@
 import Data.Semigroupoid (Semigroupoid(..))
 #endif
 import Test.QuickCheck hiding ((.&.))
-#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
+import Data.Functor.Classes (Eq2,Show2)
 #endif
 import Test.QuickCheck.Property (Property)
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,5,0)
+import Test.QuickCheck.Classes.Compat (eq2)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -39,7 +46,13 @@
 --
 -- /Note/: This property test is only available when this package is built with
 -- @base-4.9+@ or @transformers-0.5+@.
-semigroupoidLaws :: (Semigroupoid sem, Eq2 sem, Show2 sem, Arbitrary2 sem) => proxy sem -> Laws
+semigroupoidLaws :: forall proxy s.
+#if MIN_VERSION_base(4,12,0)
+  (Semigroupoid s, forall a b. (Eq a, Eq b) => Eq (s a b), forall a b. (Show a, Show b) => Show (s a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (s a b))
+#else
+  (Semigroupoid s, Eq2 s, Show2 s, Arbitrary2 s)
+#endif
+  => proxy s -> Laws
 semigroupoidLaws p = Laws "Semigroupoid"
   [ ("Associativity", semigroupoidAssociativity p)
   ]
@@ -51,16 +64,34 @@
 --
 -- /Note/: This property test is only available when this package is built with
 -- @base-4.9+@ or @transformers-0.5+@.
-commutativeSemigroupoidLaws :: (Semigroupoid sem, Eq2 sem, Show2 sem, Arbitrary2 sem) => proxy sem -> Laws
+commutativeSemigroupoidLaws :: forall proxy s.
+#if MIN_VERSION_base(4,12,0)
+  (Semigroupoid s, forall a b. (Eq a, Eq b) => Eq (s a b), forall a b. (Show a, Show b) => Show (s a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (s a b))
+#else
+  (Semigroupoid s, Eq2 s, Show2 s, Arbitrary2 s)
+#endif
+  => proxy s -> Laws
 commutativeSemigroupoidLaws p = Laws "Commutative Semigroupoid" $ lawsProperties (semigroupoidLaws p) ++
   [ ("Commutative", semigroupoidCommutativity p)
   ]
 
-semigroupoidAssociativity :: forall proxy sem. (Semigroupoid sem, Eq2 sem, Show2 sem, Arbitrary2 sem) => proxy sem -> Property
-semigroupoidAssociativity _ = property $ \(Apply2 (f :: sem Integer Integer)) (Apply2 (g :: sem Integer Integer)) (Apply2 (h :: sem Integer Integer)) -> eq2 (f `o` (g `o` h)) ((f `o` g) `o` h)
+semigroupoidAssociativity :: forall proxy s.
+#if MIN_VERSION_base(4,12,0)
+  (Semigroupoid s, forall a b. (Eq a, Eq b) => Eq (s a b), forall a b. (Show a, Show b) => Show (s a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (s a b))
+#else
+  (Semigroupoid s, Eq2 s, Show2 s, Arbitrary2 s)
+#endif
+  => proxy s -> Property
+semigroupoidAssociativity _ = property $ \(Apply2 (f :: s Integer Integer)) (Apply2 (g :: s Integer Integer)) (Apply2 (h :: s Integer Integer)) -> eq2 (f `o` (g `o` h)) ((f `o` g) `o` h)
 
-semigroupoidCommutativity :: forall proxy sem. (Semigroupoid sem, Eq2 sem, Show2 sem, Arbitrary2 sem) => proxy sem -> Property
-semigroupoidCommutativity _ = property $ \(Apply2 (f :: sem Integer Integer)) (Apply2 (g :: sem Integer Integer)) -> eq2 (f `o` g) (g `o` f)
+semigroupoidCommutativity :: forall proxy s.
+#if MIN_VERSION_base(4,12,0)
+  (Semigroupoid s, forall a b. (Eq a, Eq b) => Eq (s a b), forall a b. (Show a, Show b) => Show (s a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (s a b))
+#else
+  (Semigroupoid s, Eq2 s, Show2 s, Arbitrary2 s)
+#endif
+  => proxy s -> Property
+semigroupoidCommutativity _ = property $ \(Apply2 (f :: s Integer Integer)) (Apply2 (g :: s Integer Integer)) -> eq2 (f `o` g) (g `o` f)
 
 #endif
 
diff --git a/src/Test/QuickCheck/Classes/Traversable.hs b/src/Test/QuickCheck/Classes/Traversable.hs
--- a/src/Test/QuickCheck/Classes/Traversable.hs
+++ b/src/Test/QuickCheck/Classes/Traversable.hs
@@ -1,6 +1,10 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
+
 {-# OPTIONS_GHC -Wall #-}
 
 module Test.QuickCheck.Classes.Traversable
@@ -18,7 +22,7 @@
 #if MIN_VERSION_QuickCheck(2,10,0)
 import Test.QuickCheck.Arbitrary (Arbitrary1(..))
 #if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
-import Data.Functor.Classes
+import Data.Functor.Classes (Eq1,Show1)
 import Data.Functor.Compose
 import Data.Functor.Identity
 #endif
@@ -27,6 +31,9 @@
 import qualified Data.Set as S
 
 import Test.QuickCheck.Classes.Common
+#if MIN_VERSION_base(4,9,0) || MIN_VERSION_transformers(0,4,0)
+import Test.QuickCheck.Classes.Compat (eq1)
+#endif
 
 #if MIN_VERSION_QuickCheck(2,10,0)
 
@@ -61,10 +68,22 @@
 --
 -- * Identity: @t ('pure' x) ≡ 'pure' x@
 -- * Distributivity: @t (x '<*>' y) ≡ t x '<*>' t y@
-traversableLaws :: (Traversable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+traversableLaws ::
+#if MIN_VERSION_base(4,12,0)
+  (Traversable f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Traversable f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 traversableLaws = traversableLawsInternal
 
-traversableLawsInternal :: forall proxy f. (Traversable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
+traversableLawsInternal :: forall proxy f.
+#if MIN_VERSION_base(4,12,0)
+  (Traversable f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
+#else
+  (Traversable f, Eq1 f, Show1 f, Arbitrary1 f)
+#endif
+  => proxy f -> Laws
 traversableLawsInternal _ = Laws "Traversable"
   [ (,) "Naturality" $ property $ \(Apply (a :: f Integer)) ->
       propNestedEq1 (apTrans (traverse func4 a)) (traverse (apTrans . func4) a)
