diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Changelog for polysemy
 
+## 0.3.0.1 (2019-06-09)
+
+- Fixed a type error in the benchmark caused by deprecation of `Semantic`
+
 ## 0.3.0.0 (2019-06-01)
 
 - Removed all deprecated names
diff --git a/bench/Poly.hs b/bench/Poly.hs
--- a/bench/Poly.hs
+++ b/bench/Poly.hs
@@ -17,7 +17,7 @@
 import Polysemy.Output
 
 
-slowBeforeSpecialization :: Member (State Int) r => Semantic r Int
+slowBeforeSpecialization :: Member (State Int) r => Sem r Int
 slowBeforeSpecialization = do
   n <- get
   if n <= 0
@@ -26,7 +26,7 @@
        put $ n - 1
        slowBeforeSpecialization
 
-{-# SPECIALIZE slowBeforeSpecialization :: Semantic '[State Int] Int #-}
+{-# SPECIALIZE slowBeforeSpecialization :: Sem '[State Int] Int #-}
 
 
 countDown :: Int -> Int
@@ -34,11 +34,11 @@
   fst . run . runState s $ slowBeforeSpecialization
 
 prog
-    :: Semantic '[ State Bool
-                 , Error Bool
-                 , Resource
-                 , Lift IO
-                 ] Bool
+    :: Sem '[ State Bool
+            , Error Bool
+            , Resource
+            , Lift IO
+            ] Bool
 prog = catch @Bool (throw True) (pure . not)
 
 zoinks :: IO (Either Bool Bool)
@@ -51,9 +51,9 @@
   ReadLine :: Console m String
   WriteLine :: String -> Console m ()
 
-makeSemantic ''Console
+makeSem ''Console
 
-runConsoleBoring :: [String] -> Semantic (Console ': r) a -> Semantic r ([String], a)
+runConsoleBoring :: [String] -> Sem (Console ': r) a -> Sem r ([String], a)
 runConsoleBoring inputs
   = runFoldMapOutput (:[])
   . runListInput inputs
diff --git a/polysemy.cabal b/polysemy.cabal
--- a/polysemy.cabal
+++ b/polysemy.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 9ee186fecebe41f0688aa073f56c51a08f7f3881a86af44a4d91a6cb8b4d6005
+-- hash: 377e703e0e8b13978cd5936eac0b54f8d9ddba81bf1bdedc130d48bb4f7133dd
 
 name:           polysemy
-version:        0.3.0.0
+version:        0.3.0.1
 synopsis:       Higher-order, low-boilerplate, zero-cost free monads.
 description:    Please see the README on GitHub at <https://github.com/isovector/polysemy#readme>
 category:       Language
diff --git a/src/Polysemy/Internal.hs b/src/Polysemy/Internal.hs
--- a/src/Polysemy/Internal.hs
+++ b/src/Polysemy/Internal.hs
@@ -253,7 +253,6 @@
 hoistSem nat (Sem m) = Sem $ \k -> m $ \u -> k $ nat u
 {-# INLINE hoistSem #-}
 
-
 ------------------------------------------------------------------------------
 -- | Introduce an effect into 'Sem'. Analogous to
 -- 'Control.Monad.Class.Trans.lift' in the mtl ecosystem
@@ -272,6 +271,11 @@
 -- list.
 raiseUnder :: ∀ e2 e1 r a. Sem (e1 ': r) a -> Sem (e1 ': e2 ': r) a
 raiseUnder = hoistSem $ hoist raiseUnder_b . weakenUnder
+  where
+    weakenUnder :: ∀ m x. Union (e1 ': r) m x -> Union (e1 ': e2 ': r) m x
+    weakenUnder (Union SZ a) = Union SZ a
+    weakenUnder (Union (SS n) a) = Union (SS (SS n)) a
+    {-# INLINE weakenUnder #-}
 {-# INLINE raiseUnder #-}
 
 
@@ -285,6 +289,11 @@
 -- list.
 raiseUnder2 :: ∀ e2 e3 e1 r a. Sem (e1 ': r) a -> Sem (e1 ': e2 ': e3 ': r) a
 raiseUnder2 = hoistSem $ hoist raiseUnder2_b . weakenUnder2
+  where
+    weakenUnder2 ::  ∀ m x. Union (e1 ': r) m x -> Union (e1 ': e2 ': e3 ': r) m x
+    weakenUnder2 (Union SZ a) = Union SZ a
+    weakenUnder2 (Union (SS n) a) = Union (SS (SS (SS n))) a
+    {-# INLINE weakenUnder2 #-}
 {-# INLINE raiseUnder2 #-}
 
 
@@ -298,6 +307,11 @@
 -- list.
 raiseUnder3 :: ∀ e2 e3 e4 e1 r a. Sem (e1 ': r) a -> Sem (e1 ': e2 ': e3 ': e4 ': r) a
 raiseUnder3 = hoistSem $ hoist raiseUnder3_b . weakenUnder3
+  where
+    weakenUnder3 ::  ∀ m x. Union (e1 ': r) m x -> Union (e1 ': e2 ': e3 ': e4 ': r) m x
+    weakenUnder3 (Union SZ a) = Union SZ a
+    weakenUnder3 (Union (SS n) a) = Union (SS (SS (SS (SS n)))) a
+    {-# INLINE weakenUnder3 #-}
 {-# INLINE raiseUnder3 #-}
 
 
diff --git a/src/Polysemy/Internal/Combinators.hs b/src/Polysemy/Internal/Combinators.hs
--- a/src/Polysemy/Internal/Combinators.hs
+++ b/src/Polysemy/Internal/Combinators.hs
@@ -9,12 +9,14 @@
   , reinterpret
   , reinterpret2
   , reinterpret3
+
     -- * Higher order
   , interpretH
   , interceptH
   , reinterpretH
   , reinterpret2H
   , reinterpret3H
+
     -- * Statefulness
   , stateful
   , lazilyStateful
@@ -35,7 +37,14 @@
 swap ~(a, b) = (b, a)
 
 
+firstOrder
+    :: ((forall m x. e m x -> Tactical e m r x) -> t)
+    -> (forall m x. e m x -> Sem r x)
+    -> t
+firstOrder higher f = higher $ \(e :: e m x) -> liftT @m $ f e
+{-# INLINE firstOrder #-}
 
+
 ------------------------------------------------------------------------------
 -- | The simplest way to produce an effect handler. Interprets an effect @e@ by
 -- transforming it into other effects inside of @r@.
@@ -47,7 +56,8 @@
     -> Sem (e ': r) a
     -> Sem r a
 -- TODO(sandy): could probably give a `coerce` impl for `runTactics` here
-interpret f = interpretH $ \(e :: e m x) -> liftT @m $ f e
+interpret = firstOrder interpretH
+{-# INLINE interpret #-}
 
 
 ------------------------------------------------------------------------------
@@ -163,7 +173,7 @@
        -- ^ A natural transformation from the handled effect to the new effect.
     -> Sem (e1 ': r) a
     -> Sem (e2 ': r) a
-reinterpret f = reinterpretH $ \(e :: e m x) -> liftT @m $ f e
+reinterpret = firstOrder reinterpretH
 {-# INLINE[3] reinterpret #-}
 -- TODO(sandy): Make this fuse in with 'stateful' directly.
 
@@ -194,7 +204,7 @@
        -- ^ A natural transformation from the handled effect to the new effects.
     -> Sem (e1 ': r) a
     -> Sem (e2 ': e3 ': r) a
-reinterpret2 f = reinterpret2H $ \(e :: e m x) -> liftT @m $ f e
+reinterpret2 = firstOrder reinterpret2H
 {-# INLINE[3] reinterpret2 #-}
 
 
@@ -224,7 +234,7 @@
        -- ^ A natural transformation from the handled effect to the new effects.
     -> Sem (e1 ': r) a
     -> Sem (e2 ': e3 ': e4 ': r) a
-reinterpret3 f = reinterpret3H $ \(e :: e m x) -> liftT @m $ f e
+reinterpret3 = firstOrder reinterpret3H
 {-# INLINE[3] reinterpret3 #-}
 
 
diff --git a/src/Polysemy/Internal/Union.hs b/src/Polysemy/Internal/Union.hs
--- a/src/Polysemy/Internal/Union.hs
+++ b/src/Polysemy/Internal/Union.hs
@@ -17,9 +17,6 @@
   -- * Building Unions
   , inj
   , weaken
-  , weakenUnder
-  , weakenUnder2
-  , weakenUnder3
   -- * Using Unions
   , decomp
   , prj
@@ -191,27 +188,6 @@
 weaken :: Union r m a -> Union (e ': r) m a
 weaken (Union n a) = Union (SS n) a
 {-# INLINE weaken #-}
-
-------------------------------------------------------------------------------
--- | Like 'weaken', but introduces a new effect under the top of the stack.
-weakenUnder :: Union (e1 ': r) m a -> Union (e1 ': e2 ': r) m a
-weakenUnder (Union SZ a) = Union SZ a
-weakenUnder (Union (SS n) a) = Union (SS (SS n)) a
-{-# INLINE weakenUnder #-}
-
-------------------------------------------------------------------------------
--- | Like 'weaken', but introduces a new effect under the top of the stack.
-weakenUnder2 :: Union (e1 ': r) m a -> Union (e1 ': e2 ': e3 ': r) m a
-weakenUnder2 (Union SZ a) = Union SZ a
-weakenUnder2 (Union (SS n) a) = Union (SS (SS (SS n))) a
-{-# INLINE weakenUnder2 #-}
-
-------------------------------------------------------------------------------
--- | Like 'weaken', but introduces a new effect under the top of the stack.
-weakenUnder3 :: Union (e1 ': r) m a -> Union (e1 ': e2 ': e3 ': e4 ': r) m a
-weakenUnder3 (Union SZ a) = Union SZ a
-weakenUnder3 (Union (SS n) a) = Union (SS (SS (SS (SS n)))) a
-{-# INLINE weakenUnder3 #-}
 
 
 ------------------------------------------------------------------------------
