diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,18 @@
+# 0.10.0.0
+
+* Make `Ask`, `AskCapability`, `Await`, `JumpTo`, `Modify`, `Request`,
+  `ReturnEarly`, `Tell`, `Throw`, and `Yield` the canonical capability
+  types; `Reader`, `HandleReader`, `Consume`, `Jump`, `State`, `Coroutine`,
+  `EarlyReturn`, `Writer`, `Exception`, and `Stream` are now type synonyms.
+
+* Move `Bluefin.Internal.Pipes` to `bluefin-examples`
+
+* Remove unused failing stubs `connect` and `head'` from
+  `Bluefin.Internal`
+
+* Breaking change: separate `Prim`'s primitive state and capability
+  scope type parameters
+
 # 0.9.2.0
 
 * Bug fix: release `Reader` Vault keys when their handler scope exits.
diff --git a/bluefin-internal.cabal b/bluefin-internal.cabal
--- a/bluefin-internal.cabal
+++ b/bluefin-internal.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               bluefin-internal
-version:            0.9.2.0
+version:            0.10.0.0
 license:            MIT
 license-file:       LICENSE
 author:             Tom Ellis
@@ -96,7 +96,6 @@
       Bluefin.Internal.GadtEffect,
       Bluefin.Internal.Key,
       Bluefin.Internal.OneWayCoercible,
-      Bluefin.Internal.Pipes,
       Bluefin.Internal.Prim,
       Bluefin.Internal.System.IO,
       Bluefin.Internal.Vault
diff --git a/src/Bluefin/Internal.hs b/src/Bluefin/Internal.hs
--- a/src/Bluefin/Internal.hs
+++ b/src/Bluefin/Internal.hs
@@ -226,7 +226,7 @@
   liftBaseWith = withRunInIO
   restoreM = pure
 
-instance (e <: es) => MonadFail (EffReader (Exception String e) es) where
+instance (e <: es) => MonadFail (EffReader (Throw String e) es) where
   fail = MkEffReader . flip throw
 
 hoistReader ::
@@ -267,8 +267,8 @@
 -- `Either String` and then applying `either (throw f) pure`.
 withMonadFail ::
   (e <: es) =>
-  -- | @Exception@ to @throw@ on @fail@
-  Exception String e ->
+  -- | @Throw@ to @throw@ on @fail@
+  Throw String e ->
   -- | 'MonadFail' operation
   (forall m. (MonadFail m) => m r) ->
   -- | @MonadFail@ operation run in @Eff@
@@ -346,41 +346,41 @@
 type role StateSource nominal
 
 -- | Capability to throw an exception of type @exn@
-newtype Exception exn (e :: Effects)
+newtype Throw exn (e :: Effects)
   = MkException (forall a. exn -> Eff e a)
-  deriving (Handle) via OneWayCoercibleHandle (Exception exn)
+  deriving (Handle) via OneWayCoercibleHandle (Throw exn)
 
-type role Exception representational nominal
+type role Throw representational nominal
 
-instance (e <: es) => OneWayCoercible (Exception ex e) (Exception ex es) where
+instance (e <: es) => OneWayCoercible (Throw ex e) (Throw ex es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- | Capability to modify a reference to an @s@
-newtype State s (e :: Effects) = UnsafeMkState (IORef s)
-  deriving (Handle) via OneWayCoercibleHandle (State s)
+newtype Modify s (e :: Effects) = UnsafeMkState (IORef s)
+  deriving (Handle) via OneWayCoercibleHandle (Modify s)
 
-type role State representational nominal
+type role Modify representational nominal
 
-instance (e <: es) => OneWayCoercible (State s e) (State s es) where
+instance (e <: es) => OneWayCoercible (Modify s e) (Modify s es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- | Capability to yield a value of type @a@ and then await a value of
 -- type @b@ in response.
-newtype Coroutine a b (e :: Effects) = MkCoroutine (a -> Eff e b)
-  deriving (Handle) via OneWayCoercibleHandle (Coroutine a b)
+newtype Request a b (e :: Effects) = MkCoroutine (a -> Eff e b)
+  deriving (Handle) via OneWayCoercibleHandle (Request a b)
 
-instance (e <: es) => OneWayCoercible (Coroutine a b e) (Coroutine a b es) where
+instance (e <: es) => OneWayCoercible (Request a b e) (Request a b es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- | Capability to yield values of type @a@.  It is implemented as a
 -- 'Bluefin.Capability.Request' capability that can yield values of
 -- type @a@ and then await values of type @()@.
-type Stream a = Coroutine a ()
+type Yield a = Request a ()
 
-type Consume a = Coroutine () a
+type Await a = Request () a
 
 -- | Every Bluefin capability should have an instance of class @Handle@.
--- Built-in capabilities, such as 'Exception', 'State' and 'IOE', come with
+-- Built-in capabilities, such as 'Throw', 'Modify' and 'IOE', come with
 -- @Handle@ instances.
 --
 -- You should define a @Handle@ instance for each capability that you
@@ -392,8 +392,8 @@
 -- @
 -- data Application e = MkApplication
 --   { queryDatabase :: String -> Int -> Eff e [String],
---     applicationState :: State (Int, Bool) e,
---     logger :: Stream String e
+--     applicationState :: Modify (Int, Bool) e,
+--     logger :: Yield String e
 --   }
 --   deriving (Generic)
 --   deriving (Handle) via 'OneWayCoercibleHandle' Application
@@ -586,11 +586,11 @@
 -- | For defining 'OneWayCoercible' instances for newtypes. Example:
 --
 -- @
--- newtype Random g e = Random (State g e)
+-- newtype Random g e = Random (Modify g e)
 --   deriving (Handle) via OneWayCoercibleHandle (Random g)
 --
 -- instance (e \<: es) => OneWayCoercible (Random g e) (Random g es) where
---   oneWayCoercibleImpl = oneWayCoercibleNewtypeHandle @(State g)
+--   oneWayCoercibleImpl = oneWayCoercibleNewtypeHandle @(Modify g)
 -- @
 oneWayCoercibleNewtypeHandle ::
   forall h1 h2 e es.
@@ -755,7 +755,7 @@
 -- @
 throw ::
   (e <: es) =>
-  Exception ex e ->
+  Throw ex e ->
   -- | Value to throw
   ex ->
   Eff es a
@@ -785,7 +785,7 @@
 -- @
 try ::
   forall exn (es :: Effects) a.
-  (forall e. Exception exn e -> Eff (e :& es) a) ->
+  (forall e. Throw exn e -> Eff (e :& es) a) ->
   -- | @Left@ if the exception was thrown, @Right@ otherwise
   Eff es (Either exn a)
 try f =
@@ -805,7 +805,7 @@
   forall exn (es :: Effects) a.
   -- | If the exception is thrown, apply this handler
   (exn -> Eff es a) ->
-  (forall e. Exception exn e -> Eff (e :& es) a) ->
+  (forall e. Throw exn e -> Eff (e :& es) a) ->
   Eff es a
 handle h f =
   try f >>= \case
@@ -815,7 +815,7 @@
 -- | 'handle', but with the argument order swapped
 catch ::
   forall exn (es :: Effects) a.
-  (forall e. Exception exn e -> Eff (e :& es) a) ->
+  (forall e. Throw exn e -> Eff (e :& es) a) ->
   -- | If the exception is thrown, apply this handler
   (exn -> Eff es a) ->
   Eff es a
@@ -855,7 +855,7 @@
   forall ex es e1 e2 r.
   (e1 <: es, e2 <: es, Control.Exception.Exception ex) =>
   IOE e1 ->
-  Exception ex e2 ->
+  Throw ex e2 ->
   Eff es r ->
   -- | ͘
   Eff es r
@@ -922,7 +922,7 @@
 withStateInIO ::
   (e1 <: es, e2 <: es) =>
   IOE e1 ->
-  State s e2 ->
+  Modify s e2 ->
   (IORef s -> IO r) ->
   Eff es r
 withStateInIO io (UnsafeMkState r) k = effIO io (k r)
@@ -936,7 +936,7 @@
 -- @
 get ::
   (e <: es) =>
-  State s e ->
+  Modify s e ->
   -- | The current value of the state
   Eff es s
 get st = unsafeProvideIO $ \io -> withStateInIO io st readIORef
@@ -950,7 +950,7 @@
 -- @
 put ::
   (e <: es) =>
-  State s e ->
+  Modify s e ->
   -- | The new value of the state.  The new value is forced before
   -- writing it to the state.
   s ->
@@ -965,7 +965,7 @@
 -- @
 modify ::
   (e <: es) =>
-  State s e ->
+  Modify s e ->
   -- | Apply this function to the state.  The new value of the state
   -- is forced before writing it to the state.
   (s -> s) ->
@@ -984,10 +984,10 @@
 --   n <- 'newState' source 5
 --   total <- newState source 0
 --
---   'withJump' $ \\done -> forever $ do
---     n' <- 'Bluefin.State.get' n
---     'Bluefin.State.modify' total (+ n')
---     when (n' == 0) $ 'Bluefin.Jump.jumpTo' done
+--   'withJumpTo' $ \\done -> forever $ do
+--     n' <- 'Bluefin.Capability.Modify.get' n
+--     'Bluefin.Capability.Modify.modify' total (+ n')
+--     when (n' == 0) $ 'Bluefin.Capability.JumpTo.jumpTo' done
 --     modify n (subtract 1)
 --
 --   get total
@@ -1005,10 +1005,10 @@
 --   n <- 'newState' source 5
 --   total <- newState source 0
 --
---   'Bluefin.Jump.withJump' $ \\done -> forever $ do
---     n' <- 'Bluefin.State.get' n
---     'Bluefin.State.modify' total (+ n')
---     when (n' == 0) $ 'Bluefin.Jump.jumpTo' done
+--   'Bluefin.Capability.JumpTo.withJumpTo' $ \\done -> forever $ do
+--     n' <- 'Bluefin.Capability.Modify.get' n
+--     'Bluefin.Capability.Modify.modify' total (+ n')
+--     when (n' == 0) $ 'Bluefin.Capability.JumpTo.jumpTo' done
 --     modify n (subtract 1)
 --
 --   get total
@@ -1020,7 +1020,7 @@
   -- | The initial value for the state capability
   s ->
   -- | A new state capability
-  Eff es (State s e)
+  Eff es (Modify s e)
 newState StateSource s = unsafeProvideIO $ \io -> do
   fmap UnsafeMkState (effIO io (newIORef s))
 
@@ -1035,7 +1035,7 @@
   -- | Initial state
   s ->
   -- | Stateful computation
-  (forall e. State s e -> Eff (e :& es) a) ->
+  (forall e. Modify s e -> Eff (e :& es) a) ->
   -- | Result and final state
   Eff es (a, s)
 runState s f = do
@@ -1066,7 +1066,7 @@
 -- @
 yield ::
   (e1 <: es) =>
-  Stream a e1 ->
+  Yield a e1 ->
   -- | Yield this value from the stream
   a ->
   Eff es ()
@@ -1093,7 +1093,7 @@
 -- ([0, 0, 1, 10, 2, 20, 3, 30], ())
 -- @
 forEach ::
-  (forall e1. Coroutine a b e1 -> Eff (e1 :& es) r) ->
+  (forall e1. Request a b e1 -> Eff (e1 :& es) r) ->
   -- | Apply this effectful function for each element of the coroutine
   (a -> Eff es b) ->
   Eff es r
@@ -1127,7 +1127,7 @@
   (Foldable t, e1 <: es) =>
   -- | Yield all these values from the stream
   t a ->
-  Stream a e1 ->
+  Yield a e1 ->
   Eff es ()
 inFoldable t = for_ t . yield
 
@@ -1141,8 +1141,8 @@
 enumerate ::
   (e2 <: es) =>
   -- | ͘
-  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
-  Stream (Int, a) e2 ->
+  (forall e1. Yield a e1 -> Eff (e1 :& es) r) ->
+  Yield (Int, a) e2 ->
   Eff es r
 enumerate s = enumerateFrom 0 s
 
@@ -1157,8 +1157,8 @@
   (e2 <: es) =>
   -- | Initial value
   Int ->
-  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
-  Stream (Int, a) e2 ->
+  (forall e1. Yield a e1 -> Eff (e1 :& es) r) ->
+  Yield (Int, a) e2 ->
   Eff es r
 enumerateFrom n ss st =
   evalState n $ \i -> forEach (useImplUnder . ss) $ \s -> do
@@ -1180,10 +1180,10 @@
   Eff es r
 consumeEach k e = forEach k (\() -> e)
 
-await :: (e <: es) => Consume a e -> Eff es a
+await :: (e <: es) => Await a e -> Eff es a
 await r = yieldCoroutine r ()
 
-type EarlyReturn = Exception
+type ReturnEarly = Throw
 
 -- | Run an 'Eff' action with the ability to return early to this
 -- point.  In the language of exceptions, 'withEarlyReturn' installs
@@ -1214,7 +1214,7 @@
 -- @
 returnEarly ::
   (e <: es) =>
-  EarlyReturn r e ->
+  ReturnEarly r e ->
   -- | Return early to the handler, with this value.
   r ->
   Eff es a
@@ -1231,7 +1231,7 @@
   -- | Initial state
   s ->
   -- | Stateful computation
-  (forall e. State s e -> Eff (e :& es) a) ->
+  (forall e. Modify s e -> Eff (e :& es) a) ->
   -- | Result
   Eff es a
 evalState s f = fmap fst (runState s f)
@@ -1247,7 +1247,7 @@
   -- | Initial state
   s ->
   -- | Stateful computation
-  (forall e. State s e -> Eff (e :& es) (s -> a)) ->
+  (forall e. Modify s e -> Eff (e :& es) (s -> a)) ->
   -- | Result
   Eff es a
 withState s f = do
@@ -1300,10 +1300,10 @@
   Eff es r
 withC2 c f = withCompound c (\_ i -> f i)
 
-putC :: forall ss es e. (ss <: es) => Compound e (State Int) ss -> Int -> Eff es ()
+putC :: forall ss es e. (ss <: es) => Compound e (Modify Int) ss -> Int -> Eff es ()
 putC c i = withC2 c (\h -> put h i)
 
-getC :: forall ss es e. (ss <: es) => Compound e (State Int) ss -> Eff es Int
+getC :: forall ss es e. (ss <: es) => Compound e (Modify Int) ss -> Eff es Int
 getC c = withC2 c (\h -> get h)
 
 -- TODO: Make this (s1 <: es, s2 <: es), like withC
@@ -1327,7 +1327,7 @@
 -- ([1,2,100], ())
 -- @
 yieldToList ::
-  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
+  (forall e1. Yield a e1 -> Eff (e1 :& es) r) ->
   -- | Yielded elements and final result
   Eff es ([a], r)
 yieldToList f = do
@@ -1350,8 +1350,8 @@
 -- 3
 -- @
 withYieldToList ::
-  -- | Stream computation
-  (forall e. Stream a e -> Eff (e :& es) ([a] -> r)) ->
+  -- | Yield computation
+  (forall e. Yield a e -> Eff (e :& es) ([a] -> r)) ->
   -- | Result
   Eff es r
 withYieldToList f = do
@@ -1370,11 +1370,11 @@
 -- ([100,2,1], ())
 -- @
 yieldToReverseList ::
-  (forall e. Stream a e -> Eff (e :& es) r) ->
+  (forall e. Yield a e -> Eff (e :& es) r) ->
   -- | Yielded elements in reverse order, and final result
   Eff es ([a], r)
 yieldToReverseList f = do
-  evalState [] $ \(s :: State lo st) -> do
+  evalState [] $ \(s :: Modify lo st) -> do
     r <- forEach (useImplUnder . f) $ \i ->
       modify s (i :)
     as <- get s
@@ -1386,8 +1386,8 @@
   -- stream for which this function returns @Just@
   (a -> Maybe b) ->
   -- | Input stream
-  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
-  Stream b e2 ->
+  (forall e1. Yield a e1 -> Eff (e1 :& es) r) ->
+  Yield b e2 ->
   Eff es r
 mapMaybe f s y = forEach s $ \a -> do
   case f a of
@@ -1398,8 +1398,8 @@
 catMaybes ::
   (e2 <: es) =>
   -- | Input stream
-  (forall e1. Stream (Maybe a) e1 -> Eff (e1 :& es) r) ->
-  Stream a e2 ->
+  (forall e1. Yield (Maybe a) e1 -> Eff (e1 :& es) r) ->
+  Yield a e2 ->
   Eff es r
 catMaybes s y = mapMaybe id s y
 
@@ -1414,7 +1414,7 @@
 cycleToStream ::
   (Foldable f, e1 <: es) =>
   f a ->
-  Stream a e1 ->
+  Yield a e1 ->
   -- | ͘
   Eff es ()
 cycleToStream f y = do
@@ -1442,7 +1442,7 @@
       await source >>= yield sink
       loop (c - 1)
 
-type Jump = EarlyReturn ()
+type JumpTo = ReturnEarly ()
 
 -- |
 -- @
@@ -1450,10 +1450,10 @@
 --   n <- 'newState' source 5
 --   total <- newState source 0
 --
---   'Bluefin.Jump.withJump' $ \\done -> forever $ do
---     n' <- 'Bluefin.State.get' n
---     'Bluefin.State.modify' total (+ n')
---     when (n' == 0) $ 'Bluefin.Jump.jumpTo' done
+--   'Bluefin.Capability.JumpTo.withJumpTo' $ \\done -> forever $ do
+--     n' <- 'Bluefin.Capability.Modify.get' n
+--     'Bluefin.Capability.Modify.modify' total (+ n')
+--     when (n' == 0) $ 'Bluefin.Capability.JumpTo.jumpTo' done
 --     modify n (subtract 1)
 --
 --   get total
@@ -1471,10 +1471,10 @@
 --   n <- 'newState' source 5
 --   total <- newState source 0
 --
---   'Bluefin.Jump.withJump' $ \\done -> forever $ do
---     n' <- 'Bluefin.State.get' n
---     'Bluefin.State.modify' total (+ n')
---     when (n' == 0) $ 'Bluefin.Jump.jumpTo' done
+--   'Bluefin.Capability.JumpTo.withJumpTo' $ \\done -> forever $ do
+--     n' <- 'Bluefin.Capability.Modify.get' n
+--     'Bluefin.Capability.Modify.modify' total (+ n')
+--     when (n' == 0) $ 'Bluefin.Capability.JumpTo.jumpTo' done
 --     modify n (subtract 1)
 --
 --   get total
@@ -1482,12 +1482,12 @@
 -- @
 jumpTo ::
   (e <: es) =>
-  Jump e ->
+  JumpTo e ->
   -- | ͘
   Eff es a
 jumpTo tag = throw tag ()
 
-unwrap :: (e <: es) => Jump e -> Maybe a -> Eff es a
+unwrap :: (e <: es) => JumpTo e -> Maybe a -> Eff es a
 unwrap j = \case
   Nothing -> jumpTo j
   Just a -> pure a
@@ -1553,40 +1553,10 @@
   Eff es a
 unsafeProvideIO eff = useImplIn eff MkIOE
 
-connect ::
-  (forall e1. Coroutine a b e1 -> Eff (e1 :& es) r1) ->
-  (forall e2. a -> Coroutine b a e2 -> Eff (e2 :& es) r2) ->
-  forall e1 e2.
-  (e1 <: es, e2 <: es) =>
-  Eff
-    es
-    ( Either
-        (r1, a -> Coroutine b a e2 -> Eff es r2)
-        (r2, b -> Coroutine a b e1 -> Eff es r1)
-    )
-connect _ _ = error "connect unimplemented, sorry"
-
-head' ::
-  forall a b r es.
-  (forall e. Coroutine a b e -> Eff (e :& es) r) ->
-  forall e.
-  (e <: es) =>
-  Eff
-    es
-    ( Either
-        r
-        (a, b -> Coroutine a b e -> Eff es r)
-    )
-head' c = do
-  r <- connect c (\a _ -> pure a) @_ @es
-  pure $ case r of
-    Right r' -> Right r'
-    Left (l, _) -> Left l
-
-newtype Writer w e = Writer (Stream w e)
-  deriving (Handle) via OneWayCoercibleHandle (Writer w)
+newtype Tell w e = Tell (Yield w e)
+  deriving (Handle) via OneWayCoercibleHandle (Tell w)
 
-instance (e <: es) => OneWayCoercible (Writer w e) (Writer w es) where
+instance (e <: es) => OneWayCoercible (Tell w e) (Tell w es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- |
@@ -1602,7 +1572,7 @@
   (forall e. Writer w e -> Eff (e :& es) r) ->
   Eff es (r, w)
 runWriter f = runState mempty $ \st -> do
-  forEach (useImplUnder . f . Writer) $ \ww -> do
+  forEach (useImplUnder . f . Tell) $ \ww -> do
     modify st (<> ww)
 
 -- |
@@ -1635,20 +1605,20 @@
 -- @
 tell ::
   (e <: es) =>
-  Writer w e ->
+  Tell w e ->
   -- | ͘
   w ->
   Eff es ()
-tell (Writer y) = yield y
+tell (Tell y) = yield y
 
-type Reader :: Type -> Effects -> Type
-newtype Reader r e = MkReader (Vault.Key r)
-  deriving (Handle) via OneWayCoercibleHandle (Reader r)
+type Ask :: Type -> Effects -> Type
+newtype Ask r e = MkReader (Vault.Key r)
+  deriving (Handle) via OneWayCoercibleHandle (Ask r)
 
-instance (e <: es) => OneWayCoercible (Reader r e) (Reader r es) where
+instance (e <: es) => OneWayCoercible (Ask r e) (Ask r es) where
   oneWayCoercibleImpl = oneWayCoercible
 
-type role Reader representational nominal
+type role Ask representational nominal
 
 runReader ::
   -- | Initial value for @Reader@.
@@ -1683,7 +1653,7 @@
 ask ::
   (e <: es) =>
   -- | ͘
-  Reader r e ->
+  Ask r e ->
   Eff es r
 ask (MkReader k) = UnsafeMkEff $ \vault -> do
   v <- readIORef vault
@@ -1705,17 +1675,17 @@
 -- | Read the value modified by a function
 asks ::
   (e <: es) =>
-  Reader r e ->
+  Ask r e ->
   -- | Read the value modified by this function
   (r -> a) ->
   Eff es a
 asks r f = fmap f (ask r)
 
--- | Locally override the value in the @Reader@. It will be restored
+-- | Locally override the value in the @Ask@. It will be restored
 -- when the @local@ block ends.
 local ::
   (e1 <: es) =>
-  Reader r e1 ->
+  Ask r e1 ->
   -- | In the body, the reader value is modified by this function.
   (r -> r) ->
   -- | Body
@@ -1728,8 +1698,8 @@
     (\() -> writeIORef vault orig)
     (\() -> case k of UnsafeMkEff m -> m env)
 
-newtype HandleReader h e = UnsafeMkHandleReader (Reader (h e) e)
-  deriving (Handle) via OneWayCoercibleHandle (HandleReader h)
+newtype AskCapability h e = UnsafeMkHandleReader (Ask (h e) e)
+  deriving (Handle) via OneWayCoercibleHandle (AskCapability h)
 
 -- In general this is really tremendously unsafe because we could take
 -- an `HandleReader h e`, map it to `HandleReader h es`, write an `h
@@ -1787,14 +1757,14 @@
   -- | ͘
   Eff es r
 runHandleReader h k = do
-  runReader (mapHandle h) $ \(st :: Reader (h es) e) -> do
+  runReader (mapHandle h) $ \(st :: Ask (h es) e) -> do
     let oneWayCoerceH :: OneWayCoercion (h es) (h (e :& es))
         oneWayCoerceH = oneWayCoercion
 
     let coerceH :: Coercion (h es) (h (e :& es))
         coerceH = unsafeCoercionOfOneWayCoercion oneWayCoerceH
 
-    let mapS :: Reader (h es) e' -> Reader (h (e :& es)) e'
+    let mapS :: Ask (h es) e' -> Ask (h (e :& es)) e'
         mapS = case coerceH of Coercion -> coerce
 
     let h' :: HandleReader h (e :& es)
@@ -1804,7 +1774,7 @@
 
     useImplIn k h'
 
-instance (e <: es) => OneWayCoercible (HandleReader h e) (HandleReader h es) where
+instance (e <: es) => OneWayCoercible (AskCapability h e) (AskCapability h es) where
   oneWayCoercibleImpl = unsafeOneWayCoercible
 
 newtype ConstEffect r (e :: Effects) = MkConstEffect r
@@ -1822,33 +1792,33 @@
 
 -- Capbility synonyms
 
-type Ask = Reader
+type Reader = Ask
 
-type AskCapability = HandleReader
+type HandleReader = AskCapability
 
 -- | Capability to await values of type @a@
-type Await a = Consume a
+type Consume a = Await a
 
-type JumpTo = Jump
+type Jump = JumpTo
 
 -- | Capability to yield a value of type @a@ and then await a value of
 -- type @b@ in response.
-type Request = Coroutine
+type Coroutine = Request
 
-type ReturnEarly = EarlyReturn
+type EarlyReturn r = ReturnEarly r
 
 -- | Capability to modify a reference to an @s@
-type Modify = State
+type State = Modify
 
-type Tell = Writer
+type Writer = Tell
 
 -- | Capability to throw an exception of type @exn@
-type Throw = Exception
+type Exception = Throw
 
 -- | Capability to yield values of type @a@.  It is implemented as a
 -- 'Bluefin.Capability.Request' capability that can yield values of
 -- type @a@ and then await values of type @()@.
-type Yield a = Stream a
+type Stream a = Yield a
 
 runAsk ::
   -- | Initial value for @Ask@.
@@ -1881,7 +1851,7 @@
 -- | 'awaitYield' is 'Bluefin.Capability.Request.connectRequests'
 -- specialized to @Await@ and @Yield@, which is the most common case.
 awaitYield ::
-  -- | Starts running first. Each 'await' from the @Consume@ ...
+  -- | Starts running first. Each 'await' from the @Await@ ...
   (forall e. Await a e -> Eff (e :& es) r) ->
   -- | ... receives the value 'yield'ed from the @Yield@
   (forall e. Yield a e -> Eff (e :& es) r) ->
@@ -1930,7 +1900,7 @@
 -- 42
 -- @
 ignoreYield ::
-  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
+  (forall e1. Yield a e1 -> Eff (e1 :& es) r) ->
   -- | ͘
   Eff es r
 ignoreYield = ignoreStream
@@ -1964,7 +1934,7 @@
 -- "Returned early with 5"
 -- @
 withReturnEarly ::
-  (forall e. EarlyReturn r e -> Eff (e :& es) r) ->
+  (forall e. ReturnEarly r e -> Eff (e :& es) r) ->
   -- | ͘
   Eff es r
 withReturnEarly = withEarlyReturn
@@ -2055,7 +2025,7 @@
 runAskCapability ::
   (e1 <: es, Handle h) =>
   h e1 ->
-  (forall e. HandleReader h e -> Eff (e :& es) r) ->
+  (forall e. AskCapability h e -> Eff (e :& es) r) ->
   -- | ͘
   Eff es r
 runAskCapability = runHandleReader
@@ -2064,7 +2034,7 @@
 -- a future version.  Use 'asksCapability' instead.
 askCapability ::
   (e <: es, Handle h) =>
-  HandleReader h e ->
+  AskCapability h e ->
   -- | ͘
   Eff es (h es)
 askCapability = askHandle
@@ -2092,10 +2062,10 @@
 --   n <- 'newState' source 5
 --   total <- newState source 0
 --
---   'Bluefin.JumpTo.withJumpTo' $ \\done -> forever $ do
+--   'Bluefin.Capability.JumpTo.withJumpTo' $ \\done -> forever $ do
 --     n' <- 'Bluefin.Capability.Modify.get' n
 --     'Bluefin.Capability.Modify.modify' total (+ n')
---     when (n' == 0) $ 'Bluefin.JumpTo.jumpTo' done
+--     when (n' == 0) $ 'Bluefin.Capability.JumpTo.jumpTo' done
 --     modify n (subtract 1)
 --
 --   get total
diff --git a/src/Bluefin/Internal/CloneableHandle.hs b/src/Bluefin/Internal/CloneableHandle.hs
--- a/src/Bluefin/Internal/CloneableHandle.hs
+++ b/src/Bluefin/Internal/CloneableHandle.hs
@@ -77,34 +77,34 @@
 hcIOE = MkHandleCloner $ \io k -> do
   useImplIn k (mapHandle io)
 
--- | Cloning a @State@ copies its contents to a new @State@.  Changes
+-- | Cloning a @Modify@ copies its contents to a new @Modify@.  Changes
 -- to one will not effect the other.
-instance CloneableHandle (State s) where
+instance CloneableHandle (Modify s) where
   cloneableHandleImpl = MkCloneableHandleD hcState
 
-hcState :: HandleCloner (State s) (State s) e
+hcState :: HandleCloner (Modify s) (Modify s) e
 hcState = MkHandleCloner $ \st k -> do
   s <- get st
   evalState s $ \st' ->
     useImplIn k (mapHandle st')
 
-instance CloneableHandle (Exception a) where
+instance CloneableHandle (Throw a) where
   cloneableHandleImpl = MkCloneableHandleD hcException
 
-hcException :: HandleCloner (Exception ex) (Exception ex) e
+hcException :: HandleCloner (Throw ex) (Throw ex) e
 hcException = MkHandleCloner $ \ex k -> do
   useImplIn k (mapHandle ex)
 
-instance CloneableHandle (Reader r) where
+instance CloneableHandle (Ask r) where
   cloneableHandleImpl = MkCloneableHandleD hcReader
 
-hcReader :: HandleCloner (Reader r) (Reader r) e
+hcReader :: HandleCloner (Ask r) (Ask r) e
 hcReader = MkHandleCloner $ \r k -> do
   useImplIn k (mapHandle r)
 
--- | Cloning a @HandleReader@ copies its contents to a new
--- @HandleReader@.  Changes to one will not effect the other.
-instance (CloneableHandle h) => CloneableHandle (HandleReader h) where
+-- | Cloning an @AskCapability@ copies its contents to a new
+-- @AskCapability@.  Changes to one will not effect the other.
+instance (CloneableHandle h) => CloneableHandle (AskCapability h) where
   cloneableHandleImpl = MkCloneableHandleD hcHandleReader
 
 cloneHandleClass ::
@@ -115,7 +115,7 @@
 cloneHandleClass =
   cloneHandle2 (case cloneableHandleImpl of MkCloneableHandleD c' -> c')
 
-hcHandleReader :: (CloneableHandle h) => HandleCloner (HandleReader h) (HandleReader h) e
+hcHandleReader :: (CloneableHandle h) => HandleCloner (AskCapability h) (AskCapability h) e
 hcHandleReader = MkHandleCloner $ \hr k -> do
   asksHandle hr $ \h -> do
     cloneHandleClass h $ \h' -> do
@@ -123,18 +123,18 @@
         useImplIn k (mapHandle hr')
 
 instance
-  (TypeError (Text "Coroutine cannot be cloned. Perhaps you want an STM channel?")) =>
-  CloneableHandle (Coroutine a b)
+  (TypeError (Text "Request cannot be cloned. Perhaps you want an STM channel?")) =>
+  CloneableHandle (Request a b)
   where
   cloneableHandleImpl =
-    error "instance CloneableHandle (Coroutine a b) not implemented"
+    error "instance CloneableHandle (Request a b) not implemented"
 
 instance
-  (TypeError (Text "Writer cannot be cloned. Perhaps you want an STM channel?")) =>
-  CloneableHandle (Writer w)
+  (TypeError (Text "Tell cannot be cloned. Perhaps you want an STM channel?")) =>
+  CloneableHandle (Tell w)
   where
   cloneableHandleImpl =
-    error "instance CloneableHandle (Writer a) not implemented"
+    error "instance CloneableHandle (Tell a) not implemented"
 
 newtype (h1 :~> h2) es = MkArrow (forall e. h1 e -> h2 (e :& es))
 
@@ -254,7 +254,7 @@
 -- example:
 --
 -- @
--- data MyHandle e = MkMyHandle ('Bluefin.Exception.Exception' String e) ('Bluefin.State.State' Int e)
+-- data MyHandle e = MkMyHandle ('Bluefin.Capability.Throw.Throw' String e) ('Bluefin.Capability.Modify.Modify' Int e)
 --   deriving ('Bluefin.Compound.Generic', 'Generic1')
 --   deriving ('Bluefin.Compound.Handle') via t'Bluefin.Compound.OneWayCoercibleHandle' MyHandle
 --   deriving ('CloneableHandle') via 'GenericCloneableHandle' MyHandle
diff --git a/src/Bluefin/Internal/Exception.hs b/src/Bluefin/Internal/Exception.hs
--- a/src/Bluefin/Internal/Exception.hs
+++ b/src/Bluefin/Internal/Exception.hs
@@ -7,7 +7,7 @@
 
 import Bluefin.Internal
   ( Eff,
-    Exception (..),
+    Throw (..),
     Handle,
     OneWayCoercibleHandle (..),
     effIO,
@@ -156,7 +156,7 @@
   forall ex r a es.
   (r -> ex -> Eff es a) ->
   -- | ͘
-  MakeExceptions r a (Exception ex) es
+  MakeExceptions r a (Throw ex) es
 catchWithResource f = MkMakeExceptions $ unsafeProvideIO $ \io -> do
   scopedEx <- effIO io (SE.newException @ex)
   let hk = MkHandledKey scopedEx (flip f)
diff --git a/src/Bluefin/Internal/GadtEffect.hs b/src/Bluefin/Internal/GadtEffect.hs
--- a/src/Bluefin/Internal/GadtEffect.hs
+++ b/src/Bluefin/Internal/GadtEffect.hs
@@ -6,7 +6,7 @@
   ( Eff,
     Effects,
     Handle,
-    HandleReader,
+    AskCapability,
     OneWayCoercibleHandle (..),
     localHandle,
     mapHandle,
@@ -69,7 +69,7 @@
 --   forall es e1 e2 r.
 --   (e1 \<: es, e2 \<: es) =>
 --   t'Bluefin.IO.IOE' e1 ->
---   t'Bluefin.Exception.Exception' t'Control.Exception.IOException' e2 ->
+--   t'Bluefin.Capability.Throw.Throw' t'Control.Exception.IOException' e2 ->
 --   (forall e. 'Send' FileSystem e -> Eff (e :& es) r) ->
 --   Eff es r
 -- runFileSystem io ex = 'interpret' $ \\case
@@ -129,7 +129,7 @@
 -- augmentOp2Interpose ::
 --   (e1 \<: es, e2 \<: es) =>
 --   IOE e2 ->
---   t'Bluefin.HandleReader.HandleReader' (Send E) e1 ->
+--   t'Bluefin.Capability.AskCapability.AskCapability' (Send E) e1 ->
 --   Eff es r ->
 --   Eff es r
 -- augmentOp2Interpose io = 'interpose' $ \\fc -> \\case
@@ -149,7 +149,7 @@
 -- augmentOp2Interpose ::
 --   (e1 \<: es, e2 \<: es) =>
 --   IOE e2 ->
---   t'Bluefin.HandleReader.HandleReader' (Send E) e1 ->
+--   t'Bluefin.Capability.AskCapability.AskCapability' (Send E) e1 ->
 --   Eff es r ->
 --   Eff es r
 -- augmentOp2Interpose io = 'interpose' $ \\fc -> \\case
@@ -162,7 +162,7 @@
   -- the original effect handler, which is passed as the argument
   (Send f es -> EffectHandler f es) ->
   -- | Original effect handler
-  HandleReader (Send f) e1 ->
+  AskCapability (Send f) e1 ->
   -- | Within this block, @send@ has the implementation given above.
   Eff es r ->
   Eff es r
diff --git a/src/Bluefin/Internal/Pipes.hs b/src/Bluefin/Internal/Pipes.hs
deleted file mode 100644
--- a/src/Bluefin/Internal/Pipes.hs
+++ /dev/null
@@ -1,285 +0,0 @@
-module Bluefin.Internal.Pipes where
-
-import Bluefin.Internal
-  ( Coroutine,
-    Eff,
-    IOE,
-    effIO,
-    evalState,
-    forEach,
-    get,
-    mapHandle,
-    put,
-    receiveStream,
-    returnEarly,
-    useImpl,
-    useImplIn,
-    withReturnEarly,
-    yieldCoroutine,
-    (:&),
-    type (<:),
-  )
-import Bluefin.Internal qualified
-import Control.Monad (forever)
-import Data.Foldable (for_)
-import Data.Void (Void, absurd)
-import Prelude hiding (break, print, takeWhile)
-import Prelude qualified
-
-data Proxy a' a b' b e = MkProxy (Coroutine a' a e) (Coroutine b b' e)
-
-type Pipe a = Proxy () a ()
-
-type Producer = Proxy Void () ()
-
-type Consumer a = Pipe a Void
-
-type Effect = Producer Void
-
-infixl 7 >->
-
-(>->) ::
-  (e1 <: es) =>
-  (forall e. Proxy a' a () b e -> Eff (e :& es) r) ->
-  (forall e. Proxy () b c' c e -> Eff (e :& es) r) ->
-  Proxy a' a c' c e1 ->
-  -- | ͘
-  Eff es r
-(>->) k1 k2 (MkProxy c1 c2) =
-  receiveStream
-    (\c -> useImplIn k2 (MkProxy (mapHandle c) (mapHandle c2)))
-    (\s -> useImplIn k1 (MkProxy (mapHandle c1) (mapHandle s)))
-
-infixr 7 <-<
-
-(<-<) ::
-  (e1 <: es) =>
-  (forall e. Proxy () b c' c e -> Eff (e :& es) r) ->
-  (forall e. Proxy a' a () b e -> Eff (e :& es) r) ->
-  Proxy a' a c' c e1 ->
-  -- | ͘
-  Eff es r
-k1 <-< k2 = k2 >-> k1
-
-for ::
-  (e1 <: es) =>
-  (forall e. Proxy x' x b' b e -> Eff (e :& es) a') ->
-  (b -> forall e. Proxy x' x c' c e -> Eff (e :& es) b') ->
-  Proxy x' x c' c e1 ->
-  -- | ͘
-  Eff es a'
-for k1 k2 (MkProxy c1 c2) =
-  forEach (\bk -> useImplIn k1 (MkProxy (mapHandle c1) (mapHandle bk))) $ \b_ ->
-    useImplIn (k2 b_) (MkProxy (mapHandle c1) (mapHandle c2))
-
-infixr 4 ~>
-
-(~>) ::
-  (e1 <: es) =>
-  (a -> forall e. Proxy x' x b' b e -> Eff (e :& es) a') ->
-  (b -> forall e. Proxy x' x c' c e -> Eff (e :& es) b') ->
-  a ->
-  Proxy x' x c' c e1 ->
-  -- | ͘
-  Eff es a'
-(k1 ~> k2) a = for (k1 a) k2
-
-infixl 4 <~
-
-(<~) ::
-  (e1 <: es) =>
-  (b -> forall e. Proxy x' x c' c e -> Eff (e :& es) b') ->
-  (a -> forall e. Proxy x' x b' b e -> Eff (e :& es) a') ->
-  a ->
-  Proxy x' x c' c e1 ->
-  -- | ͘
-  Eff es a'
-k2 <~ k1 = k1 ~> k2
-
-reverseProxy :: Proxy a' a b' b e -> Proxy b b' a a' e
-reverseProxy (MkProxy c1 c2) = MkProxy c2 c1
-
-infixl 5 >~
-
-(>~) ::
-  (e1 <: es) =>
-  (forall e. Proxy a' a y' y e -> Eff (e :& es) b) ->
-  (forall e. Proxy () b y' y e -> Eff (e :& es) c) ->
-  Proxy a' a y' y e1 ->
-  -- | ͘
-  Eff es c
-(>~) k1 k2 p =
-  for
-    ( \p1 ->
-        k2 (reverseProxy p1)
-    )
-    (\() p1 -> k1 (reverseProxy p1))
-    (reverseProxy p)
-
-infixr 5 ~<
-
-(~<) ::
-  (e1 <: es) =>
-  (forall e. Proxy () b y' y e -> Eff (e :& es) c) ->
-  (forall e. Proxy a' a y' y e -> Eff (e :& es) b) ->
-  Proxy a' a y' y e1 ->
-  -- | ͘
-  Eff es c
-(~<) k1 k2 = (>~) k2 k1
-
-cat :: Pipe a a e -> Eff (e :& es) r
-cat (MkProxy c1 c2) = forever $ do
-  a <- yieldCoroutine c1 ()
-  yieldCoroutine c2 a
-
-runEffect ::
-  (forall e. Effect e -> Eff (e :& es) r) ->
-  -- | ͘
-  Eff es r
-runEffect k =
-  forEach
-    ( \c1 ->
-        forEach
-          ( \c2 ->
-              useImplIn
-                k
-                (MkProxy (mapHandle c1) (mapHandle c2))
-          )
-          absurd
-    )
-    absurd
-
-yield ::
-  (e <: es) =>
-  Proxy x1 x () a e ->
-  a ->
-  -- | ͘
-  Eff es ()
-yield (MkProxy _ c) = Bluefin.Internal.yield c
-
-await :: (e <: es) => Proxy () a y' y e -> Eff es a
-await (MkProxy c _) = yieldCoroutine c ()
-
--- | @pipe@'s 'next' doesn't exist in Bluefin
-next :: ()
-next = ()
-
-each ::
-  (Foldable f) =>
-  f a ->
-  Proxy x' x () a e ->
-  -- | ͘
-  Eff (e :& es) ()
-each f p = for_ f (yield p)
-
-repeatM ::
-  (e <: es) =>
-  Eff es a ->
-  Proxy x' x () a e ->
-  -- | ͘
-  Eff es r
-repeatM e p = forever $ do
-  a <- e
-  yield p a
-
-replicateM ::
-  (e <: es) =>
-  Int ->
-  Eff es a ->
-  Proxy x' x () a e ->
-  -- | ͘
-  Eff es ()
-replicateM n e p = for_ [0 .. n] $ \_ -> do
-  a <- e
-  yield p a
-
-print ::
-  (e2 <: es, e1 <: es, Show a) =>
-  IOE e1 ->
-  Consumer a e2 ->
-  -- | ͘
-  Eff es r
-print io p = forever $ do
-  a <- await p
-  effIO io (Prelude.print a)
-
-unfoldr ::
-  (e <: es) =>
-  (s -> Eff es (Either r (a, s))) ->
-  s ->
-  Proxy x1 x () a e ->
-  -- | ͘
-  Eff es r
-unfoldr next_ sInit p =
-  withReturnEarly $ \break -> evalState sInit $ \ss -> forever $ do
-    s <- get ss
-    useImpl (next_ s) >>= \case
-      Left r -> returnEarly break r
-      Right (a, s') -> do
-        put ss s'
-        yield p a
-
-mapM_ ::
-  (e <: es) =>
-  (a -> Eff es ()) ->
-  Proxy () a b b' e ->
-  -- | ͘
-  Eff es r
-mapM_ f = for cat (\a _ -> useImpl (f a))
-
-drain ::
-  (e <: es) =>
-  Proxy () b c' c e ->
-  -- | ͘
-  Eff es r
-drain = for cat (\_ _ -> pure ())
-
-map ::
-  (e <: es) =>
-  (a -> b) ->
-  Pipe a b e ->
-  -- | ͘
-  Eff es r
-map f = for cat (\a p1 -> yield p1 (f a))
-
-mapM ::
-  (e <: es) =>
-  (a -> Eff es b) ->
-  Pipe a b e ->
-  -- | ͘
-  Eff es r
-mapM f = for cat $ \a p -> do
-  b_ <- useImpl (f a)
-  yield p b_
-
-takeWhile' ::
-  (e <: es) =>
-  (r -> Bool) ->
-  Pipe r r e ->
-  -- | ͘
-  Eff es r
-takeWhile' predicate p = withReturnEarly $ \early -> forever $ do
-  a <- await p
-  if predicate a
-    then yield p a
-    else returnEarly early a
-
-stdinLn ::
-  (e1 <: es, e2 <: es) =>
-  IOE e1 ->
-  Producer String e2 ->
-  -- | ͘
-  Eff es r
-stdinLn io c = forever $ do
-  line <- effIO io getLine
-  yield c line
-
-stdoutLn ::
-  (e1 <: es, e2 <: es) =>
-  IOE e1 ->
-  Consumer String e2 ->
-  -- | ͘
-  Eff es r
-stdoutLn io c = forever $ do
-  line <- await c
-  effIO io (putStrLn line)
diff --git a/src/Bluefin/Internal/Prim.hs b/src/Bluefin/Internal/Prim.hs
--- a/src/Bluefin/Internal/Prim.hs
+++ b/src/Bluefin/Internal/Prim.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DerivingVia #-}
 {-# LANGUAGE MagicHash #-}
+{-# LANGUAGE RoleAnnotations #-}
 {-# LANGUAGE UnboxedTuples #-}
 
 module Bluefin.Internal.Prim where
@@ -21,19 +22,23 @@
     unsafeOneWayCoercible,
   )
 import Control.Monad.Primitive qualified as P
+import Data.Kind (Type)
 import GHC.Exts (State#)
 import Unsafe.Coerce (unsafeCoerce)
 
-data Prim (e :: Effects) = UnsafeMkPrim
-  deriving (Handle) via OneWayCoercibleHandle Prim
+type Prim :: Effects -> Effects -> Type
+data Prim e1 e2 = UnsafeMkPrim
+  deriving (Handle) via OneWayCoercibleHandle (Prim e1)
 
+type role Prim nominal nominal
+
 data PrimStateEff (es :: Effects)
 
-instance (e <: es) => OneWayCoercible (Prim e) (Prim es) where
+instance (e2 <: es) => OneWayCoercible (Prim e1 e2) (Prim e1 es) where
   oneWayCoercibleImpl = unsafeOneWayCoercible
 
 runPrim ::
-  (forall e. Prim e -> Eff (e :& es) r) ->
+  (forall e. Prim e e -> Eff (e :& es) r) ->
   -- | ͘
   Eff es r
 runPrim k = makeOp (k UnsafeMkPrim)
@@ -44,9 +49,9 @@
 unsafeCoerceStateM = unsafeCoerce
 
 primitive ::
-  forall e1 es a.
-  (e1 <: es) =>
-  Prim e1 ->
+  forall e1 e2 es a.
+  (e2 <: es) =>
+  Prim e1 e2 ->
   (State# (PrimStateEff e1) -> (# State# (PrimStateEff e1), a #)) ->
   -- | ͘
   Eff es a
