diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Changelog for polysemy-check
 
+## v0.2.0.0 (2021-10-09)
+
+- Updated the signature of `prepropEquivalent` to take a `Proxy r`. This lets
+    you bind the `r` type variable, and use it as an argument to
+    `arbitraryAction` et al.
+
 ## v0.1.0.0 (2021-10-08)
 
 - Released!
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.1.0.0
+version:        0.2.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
@@ -29,6 +29,7 @@
   , GenericK
   ) where
 
+import Data.Proxy
 import Generics.Kind (GenericK)
 import Generics.Kind.TH (deriveGenericK)
 import Polysemy
@@ -128,13 +129,13 @@
        -- be lifted into 'IO' via 'pure' after the final 'run'.
     -> (forall a. Sem r2 a -> IO a)
        -- ^ The second interpreter to prove equivalence for.
-    -> (forall r. Members effs r => Gen (Sem r x))
+    -> (forall r. Proxy r -> Members effs r => Gen (Sem r x))
        -- ^ A generator producing arbitrary programs in @r@. The property will
        -- hold true if both interpreters produce the same output for every
        -- program generated by this.
     -> Property
 prepropEquivalent int1 int2 mksem = property $ do
-  SomeSem sem <- liftGen @effs @x mksem
+  SomeSem sem <- liftGen @effs @x $ mksem Proxy
   pure $ ioProperty $ do
     a1 <- int1 sem
     a2 <- int2 sem
diff --git a/test/EquivSpec.hs b/test/EquivSpec.hs
--- a/test/EquivSpec.hs
+++ b/test/EquivSpec.hs
@@ -5,14 +5,14 @@
 
 module EquivSpec where
 
+import Data.IORef (newIORef)
+import Data.Proxy (Proxy)
 import Polysemy
 import Polysemy.Check
+import Polysemy.State
 import Test.Hspec
-import Test.QuickCheck
 import Test.Hspec.QuickCheck
-import Polysemy.State
-import Data.IORef (newIORef)
-import Unsafe.Coerce (unsafeCoerce)
+import Test.QuickCheck
 
 
 spec :: Spec
@@ -23,15 +23,11 @@
       prepropEquivalent @'[State Int] @Int
         (runPureState s0)
         (runIOState s0)
-        $ ((do
+        $ \(_ :: Proxy r) -> do
             SomeAction e1 <- arbitraryAction @(State Int) @r
             SomeAction e2 <- arbitraryAction @(State Int) @r
-            SomeAction e3 <- arbitraryAction @(State Int) @r
-            -- TODO(sandy): e3 has an existential type! GHC doesn't care, but
-            -- AFAIK, thereis no syntax to return this type, since it doesn't
-            -- exist when we bind 'a' below.
-            pure $ send e1 >> send e2 >> unsafeCoerce (send e3)
-           ) :: forall r a. Member (State Int) r => Gen (Sem r a))
+            e3 <- arbitraryActionOfType @(State Int) @Int @r
+            pure $ send e1 >> send e2 >> send e3
 
 
 runPureState :: Int -> Sem '[State Int] a -> IO a
