diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # Changelog for polysemy-check
 
+## v0.8.0.0 (2021-10-21)
+
+- `prepropCommutative` now accepts arbitrary rows to draw actions from, rather
+    than single effects.
+
 ## v0.7.0.0 (2021-10-16)
 
 - Removed the `x` type variable from `prepropEquivalent`, since it is safe to
diff --git a/polysemy-check.cabal b/polysemy-check.cabal
--- a/polysemy-check.cabal
+++ b/polysemy-check.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           polysemy-check
-version:        0.7.0.0
+version:        0.8.0.0
 synopsis:       QuickCheck for Polysemy
 description:    Please see the README on GitHub at <https://github.com/polysemy-research/polysemy-check#readme>
 category:       Polysemy
diff --git a/src/Polysemy/Check.hs b/src/Polysemy/Check.hs
--- a/src/Polysemy/Check.hs
+++ b/src/Polysemy/Check.hs
@@ -55,7 +55,7 @@
 -- For example,
 --
 -- @
--- 'prepropCommutative' \@(State Int) \@Trace \@EffStack runEffStack
+-- 'prepropCommutative' \@'[State Int] \@'[Trace] \@EffStack runEffStack
 -- @
 --
 -- will interleave random @State Int@ and @Trace@ actions, within a bigger
@@ -63,13 +63,13 @@
 -- permuting the @State Int@ and @Trace@ effects changes the outcome of the
 -- entire computation.
 prepropCommutative
-    :: forall e1 e2 r f
+    :: forall effs1 effs2 r f
      . ( forall a. Show a => Show (f a)
        , forall a. Eq a => Eq (f a)
        )
     => ( ArbitraryEff r r
-       , ArbitraryEff '[e1] r
-       , ArbitraryEff '[e2] r
+       , ArbitraryEff effs1 r
+       , ArbitraryEff effs2 r
        )
     => (forall a. Sem r a -> IO (f a))
        -- ^ An interpreter for the effect stack down to 'IO'. Pure effect
@@ -77,8 +77,8 @@
     -> Property
 prepropCommutative lower = property @(Gen Property) $ do
   SomeEff m1 <- arbitraryActionFromRow @r @r
-  SomeEff e1 <- arbitraryActionFromRow @'[e1] @r
-  SomeEff e2 <- arbitraryActionFromRow @'[e2] @r
+  SomeEff e1 <- arbitraryActionFromRow @effs1 @r
+  SomeEff e2 <- arbitraryActionFromRow @effs2 @r
   SomeEff m2 <- arbitraryActionFromRow @r @r
   pure $
     counterexample "Effects are not commutative!" $
diff --git a/test/CommutativeSpec.hs b/test/CommutativeSpec.hs
--- a/test/CommutativeSpec.hs
+++ b/test/CommutativeSpec.hs
@@ -14,15 +14,15 @@
 spec :: Spec
 spec = do
   prop "State commutes with Trace" $
-    prepropCommutative @(State Int) @Trace @TestEffs $
+    prepropCommutative @'[State Int] @'[Trace] @TestEffs $
       runTestEffs
 
   prop "State does not commute with itself" $ expectFailure $
-    prepropCommutative @(State Int) @(State Int) @TestEffs $
+    prepropCommutative @'[State Int] @'[State Int] @TestEffs $
       runTestEffs
 
   prop "Error does not commute with State (really: we can do Arbitrary stuff on Error)" $ expectFailure $
-    prepropCommutative @(Error Int) @(State Int) @[Error Int, State Int] $
+    prepropCommutative @'[Error Int] @'[State Int] @'[Error Int, State Int] $
       pure . Compose . run . runState 0 . runError
 
 
