diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.5.1.0
+
+* Add `<:` type synonym for `:>`
+
 # 0.5.0.0
 
 * Fix dodgy `Bluefin.Primitive.Internal.primitive` implementation
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.5.0.0
+version:            0.5.1.0
 license:            MIT
 license-file:       LICENSE
 author:             Tom Ellis
@@ -32,6 +32,8 @@
       EmptyDataDeriving
       ExistentialQuantification
       ExplicitForAll
+      -- ExplicitNamespaces is in GHC2024 but not GHC2021
+      ExplicitNamespaces
       -- Not available until 9.2
       -- FieldSelectors
       FlexibleContexts
@@ -63,7 +65,6 @@
       TypeApplications
       TypeOperators
       TypeSynonymInstances
-      NoExplicitNamespaces
       -- Others
       DataKinds
       DerivingStrategies
diff --git a/src/Bluefin/Internal.hs b/src/Bluefin/Internal.hs
--- a/src/Bluefin/Internal.hs
+++ b/src/Bluefin/Internal.hs
@@ -43,11 +43,14 @@
 import Unsafe.Coerce (unsafeCoerce)
 import Prelude hiding (drop, head, read, return)
 
+-- | Each inhabitant of @Effects@ is a set of effect tags, used for
+-- effect tracking to ensure that effects don't escape the scope of
+-- their handler
 data Effects = Union Effects Effects
 
 -- | @type (:&) :: Effects -> Effects -> Effects@
 --
--- Union of effects
+-- Union of sets of effect tags
 infixr 9 :&
 
 type (:&) = Union
@@ -58,10 +61,10 @@
 
 type role Eff nominal representational
 
-instance (e :> es) => OneWayCoercible (Eff e) (Eff es) where
+instance (e <: es) => OneWayCoercible (Eff e) (Eff es) where
   oneWayCoercibleImpl = oneWayCoercible
 
-instance (e :> es) => OneWayCoercible (Eff e r) (Eff es r) where
+instance (e <: es) => OneWayCoercible (Eff e r) (Eff es r) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- | Because doing 'IO' operations inside 'Eff' requires a value-level
@@ -70,7 +73,7 @@
 newtype EffReader r es a = MkEffReader {unEffReader :: r -> Eff es a}
   deriving (Functor, Applicative, Monad) via (Reader.ReaderT r (Eff es))
 
-instance (e :> es) => MonadIO (EffReader (IOE e) es) where
+instance (e <: es) => MonadIO (EffReader (IOE e) es) where
   liftIO = MkEffReader . flip effIO
 
 effReader :: (r -> Eff es a) -> EffReader r es a
@@ -81,7 +84,7 @@
 
 -- | Deprecated.  Use 'withEffToIO_' instead.
 withEffToIO ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   -- | Continuation with the unlifting function in scope.
   ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) ->
   IOE e2 ->
@@ -89,7 +92,7 @@
 withEffToIO k io = effIO io (k (\f -> unsafeUnEff (f io)))
 
 withEffToIO' ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   -- | Continuation with the unlifting function in scope.
   IOE e2 ->
   ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) ->
@@ -99,7 +102,7 @@
 -- | This is equivalent to the 'withRunInIO' method of
 -- 'MonadUnliftIO', but written in Bluefin-style.
 withEffToIO_ ::
-  (e :> es) =>
+  (e <: es) =>
   IOE e ->
   -- | Continuation with the unlifting function in scope.
   ((forall r. Eff es r -> IO r) -> IO a) ->
@@ -109,7 +112,7 @@
 
 -- We can do the old API in terms of withEffToIO_
 withEffToIO_' ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   IOE e2 ->
   -- | Continuation with the unlifting function in scope.
   ((forall r. (forall e1. IOE e1 -> Eff (e1 :& es) r) -> IO r) -> IO a) ->
@@ -121,7 +124,7 @@
 -- through all the consequences.
 
 -- | You probably want to use 'withEffToIO_' instead.
-instance (e :> es) => MonadUnliftIO (EffReader (IOE e) es) where
+instance (e <: es) => MonadUnliftIO (EffReader (IOE e) es) where
   withRunInIO ::
     ((forall a. EffReader (IOE e) es a -> IO a) -> IO b) ->
     EffReader (IOE e) es b
@@ -132,7 +135,7 @@
           effToIO (f io)
 
 race ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   (forall e. IOE e -> Eff (e :& es) a) ->
   (forall e. IOE e -> Eff (e :& es) a) ->
   IOE e2 ->
@@ -198,7 +201,7 @@
 streamConsume s c = consumeStream c s
 
 zipCoroutines ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Coroutine (a1, a2) b e1 ->
   (forall e. Coroutine a1 b e -> Eff (e :& es) r) ->
   (forall e. Coroutine a2 b e -> Eff (e :& es) r) ->
@@ -215,15 +218,15 @@
           a2' <- yieldCoroutine c2 b'
           put ass (a1', a2')
 
-instance (e :> es) => MonadBase IO (EffReader (IOE e) es) where
+instance (e <: es) => MonadBase IO (EffReader (IOE e) es) where
   liftBase = liftIO
 
-instance (e :> es) => MonadBaseControl IO (EffReader (IOE e) es) where
+instance (e <: es) => MonadBaseControl IO (EffReader (IOE e) es) where
   type StM (EffReader (IOE e) es) a = a
   liftBaseWith = withRunInIO
   restoreM = pure
 
-instance (e :> es) => MonadFail (EffReader (Exception String e) es) where
+instance (e <: es) => MonadFail (EffReader (Exception String e) es) where
   fail = MkEffReader . flip throw
 
 hoistReader ::
@@ -243,7 +246,7 @@
 -- This is not really any better than just running the action in
 -- `IO`.
 withMonadIO ::
-  (e :> es) =>
+  (e <: es) =>
   IOE e ->
   -- | 'MonadIO' operation
   (forall m. (MonadIO m) => m r) ->
@@ -263,7 +266,7 @@
 -- This is not really any better than just running the action in
 -- `Either String` and then applying `either (throw f) pure`.
 withMonadFail ::
-  (e :> es) =>
+  (e <: es) =>
   -- | @Exception@ to @throw@ on @fail@
   Exception String e ->
   -- | 'MonadFail' operation
@@ -288,7 +291,7 @@
 insertSecond :: Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r
 insertSecond = insertManySecond
 
-insertManySecond :: (b :> c) => Eff (c1 :& b) r -> Eff (c1 :& c) r
+insertManySecond :: (b <: c) => Eff (c1 :& b) r -> Eff (c1 :& c) r
 insertManySecond = weakenEff (bimap has has)
 
 assoc1Eff :: Eff ((a :& b) :& c) r -> Eff (a :& (b :& c)) r
@@ -300,7 +303,7 @@
 mergeEff :: Eff (a :& a) r -> Eff a r
 mergeEff = weakenEff (merge ZW)
 
-inContext :: (e2 :> e1) => Eff (e1 :& e2) r -> Eff e1 r
+inContext :: (e2 <: e1) => Eff (e1 :& e2) r -> Eff e1 r
 inContext = weakenEff (subsume1 has)
 
 -- | Used to define dynamic effects.
@@ -308,12 +311,12 @@
 makeOp = inContext
 
 -- | Used to define dynamic effects.
-useImpl :: (e :> es) => Eff e r -> Eff es r
+useImpl :: (e <: es) => Eff e r -> Eff es r
 useImpl = weakenEff has
 
 -- | Like 'useImpl'
 useImplUnder ::
-  (e :> es) =>
+  (e <: es) =>
   Eff (e1 :& e) r ->
   -- | ͘
   Eff (e1 :& es) r
@@ -321,7 +324,7 @@
 
 -- | Used to define handlers of compound effects.
 useImplIn ::
-  (e :> es) =>
+  (e <: es) =>
   (t -> Eff (es :& e) r) ->
   t ->
   -- | ͘
@@ -330,7 +333,7 @@
 
 -- | Deprecated.  Use 'useImplUnder' instead.
 useImplWithin ::
-  (e :> es) =>
+  (e <: es) =>
   (t -> Eff (e1 :& e) r) ->
   t ->
   -- | ͘
@@ -349,7 +352,7 @@
 
 type role Exception representational nominal
 
-instance (e :> es) => OneWayCoercible (Exception ex e) (Exception ex es) where
+instance (e <: es) => OneWayCoercible (Exception ex e) (Exception ex es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- | A handle to a strict mutable state of type @s@
@@ -358,7 +361,7 @@
 
 type role State representational nominal
 
-instance (e :> es) => OneWayCoercible (State s e) (State s es) where
+instance (e <: es) => OneWayCoercible (State s e) (State s es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- | A handle to a coroutine that yields values of type @a@ and then
@@ -366,7 +369,7 @@
 newtype Coroutine a b (e :: Effects) = MkCoroutine (a -> Eff e b)
   deriving (Handle) via OneWayCoercibleHandle (Coroutine a b)
 
-instance (e :> es) => OneWayCoercible (Coroutine a b e) (Coroutine a b es) where
+instance (e <: es) => OneWayCoercible (Coroutine a b e) (Coroutine a b es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- | A handle to a stream that yields values of type @a@.  It is
@@ -395,7 +398,7 @@
 --   deriving (Generic)
 --   deriving (Handle) via 'OneWayCoercibleHandle' Application
 --
--- instance (e :> es) => 'OneWayCoercible' (Application e) (Application es) where
+-- instance (e \<: es) => 'OneWayCoercible' (Application e) (Application es) where
 --   oneWayCoercibleImpl = 'gOneWayCoercible'
 -- @
 --
@@ -403,7 +406,7 @@
 -- you can instead use
 --
 -- @
--- instance (e :> es) => OneWayCoercible (MyHandle e) (MyHandle es) where
+-- instance (e \<: es) => OneWayCoercible (MyHandle e) (MyHandle es) where
 --   oneWayCoercibleImpl = 'oneWayCoercibleTrustMe' $ \\h -> \<mapHandle definition\>
 -- @
 class Handle (h :: Effects -> Type) where
@@ -426,7 +429,7 @@
 --   deriving (Generic)
 --   deriving (Handle) via 'OneWayCoercibleHandle' MyHandle
 --
--- instance (e :> es) => 'OneWayCoercible' (MyHandle e) (MyHandle es) where
+-- instance (e \<: es) => 'OneWayCoercible' (MyHandle e) (MyHandle es) where
 --   'oneWayCoercibleImpl' = 'gOneWayCoercible'
 -- @
 --
@@ -434,23 +437,23 @@
 -- you can instead use
 --
 -- @
--- instance (e :> es) => OneWayCoercible (MyHandle e) (MyHandle es) where
+-- instance (e \<: es) => OneWayCoercible (MyHandle e) (MyHandle es) where
 --   oneWayCoercibleImpl = 'oneWayCoercibleTrustMe' $ \\h -> \<mapHandle definition\>
 -- @
-mapHandle :: forall h e es. (Handle h, e :> es) => h e -> h es
+mapHandle :: forall h e es. (Handle h, e <: es) => h e -> h es
 mapHandle = case handleDictImpl @h of MkHandleDict -> oneWayCoerce
 
 withHandle ::
   forall h r.
   (Handle h) =>
-  ((forall e es. (e :> es) => OneWayCoercible (h e) (h es)) => r) ->
+  ((forall e es. (e <: es) => OneWayCoercible (h e) (h es)) => r) ->
   r
 withHandle r = case handleDictImpl @h of MkHandleDict -> r
 
 type HandleDict :: (Effects -> Type) -> Type
 data HandleDict h where
   MkHandleDict ::
-    (forall e es. (e :> es) => OneWayCoercible (h e) (h es)) =>
+    (forall e es. (e <: es) => OneWayCoercible (h e) (h es)) =>
     HandleDict h
 
 type role HandleDict nominal
@@ -458,7 +461,7 @@
 -- The essential properties of HandleD h are
 --
 -- (defining Handle' h =
---    forall e es. (e :> es) => OneWayCoercible (h e) (h es))
+--    forall e es. (e <: es) => OneWayCoercible (h e) (h es))
 --
 -- 1. It can be created by having Handle' h in scope
 --
@@ -488,7 +491,7 @@
 handleDictOfHandleD :: HandleD h -> HandleDict h
 -- SPJ suggests this might be safe on ghc-devs
 --
---https://mailman.haskell.org/archives/list/ghc-devs@haskell.org/thread/A4AJPPA3WSORHKCMFWAFX26XNQQVYT5R/
+-- https://mailman.haskell.org/archives/list/ghc-devs@haskell.org/thread/A4AJPPA3WSORHKCMFWAFX26XNQQVYT5R/
 handleDictOfHandleD (MkHandleD f) = unsafeCoerce f
 
 handleDictImpl :: (Handle h) => HandleDict h
@@ -498,12 +501,12 @@
 
 handleOneWayCoercible ::
   forall h.
-  (forall e es. (e :> es) => OneWayCoercible (h e) (h es)) =>
+  (forall e es. (e <: es) => OneWayCoercible (h e) (h es)) =>
   -- | ͘
   HandleD h
 -- SPJ suggests this might be safe on ghc-devs
 --
---https://mailman.haskell.org/archives/list/ghc-devs@haskell.org/thread/A4AJPPA3WSORHKCMFWAFX26XNQQVYT5R/
+-- https://mailman.haskell.org/archives/list/ghc-devs@haskell.org/thread/A4AJPPA3WSORHKCMFWAFX26XNQQVYT5R/
 handleOneWayCoercible = MkHandleD (unsafeCoerce (MkHandleDict @h))
 
 instance (Handle h) => Handle (Rec1 h) where
@@ -529,8 +532,8 @@
 -- (N.B. it must not be literally @mapHandle@ otherwise you'll have a
 -- circular definition!)
 oneWayCoercibleTrustMe ::
-  (e :> es) =>
-  (forall e' es'. (e' :> es') => h e' -> h es') ->
+  (e <: es) =>
+  (forall e' es'. (e' <: es') => h e' -> h es') ->
   -- | ͘
   OneWayCoercibleD (h e) (h es)
 -- Forcing the argument doesn't do much of a check, but it is
@@ -560,7 +563,7 @@
 
 instance
   forall h.
-  (forall e' es'. (e' :> es') => OneWayCoercible (OneWayCoercibleHandle h e') (OneWayCoercibleHandle h es')) =>
+  (forall e' es'. (e' <: es') => OneWayCoercible (OneWayCoercibleHandle h e') (OneWayCoercibleHandle h es')) =>
   Handle (OneWayCoercibleHandle h)
   where
   handleImpl = handleOneWayCoercible
@@ -635,9 +638,37 @@
 subsume2 :: (e1 `In` e2) -> (e1 :& e2) `In` e2
 subsume2 i = cmp (bimap i (eq ZW)) (merge ZW)
 
--- | Effect subset constraint
+-- | The subset constraint on sets of effect tags
+--
+-- Please use the type synonym '<:' instead of @:>@.  The former is a
+-- better name for this constraint and @:>@ will be renamed @<:@ in a
+-- future version.
 class (es1 :: Effects) :> (es2 :: Effects)
 
+-- | The subset constraint on sets of effect tags.  @<:@ is a type
+-- operator (see the extension @TypeOperators@) so in order to import
+-- it you need to use the @ExplicitNamespaces@ extension and the
+-- @type@ import qualifier, like this:
+--
+-- @
+-- {-# LANUGAGE ExplicitNamespaces #-}
+-- import Bluefin.Eff (type (<:))
+-- @
+--
+-- \"@<:@\" is a synonym for \"':>'\".  \"@<:@\" is a better name for
+-- this constraint than \"@:>@\" because it is more evocative of
+-- mathematical relations like @<@, @<=@, @⊂@ and @⊆@ which hold when
+-- the argument on the left of the operator is "smaller than" the
+-- argument on the right.  In the case of @<:@ we have that @e1 <: e2@
+-- when the set of effect tags @e1@ is a subset of or equal to @e2@,
+-- i.e. "@e1@ is smaller than (or equal to) @e2@".  For example, the
+-- following constraints hold (note that ':&' is the union of sets of
+-- effect tags):
+--
+-- * @e <: e@
+-- * @e <: (e1 :& ... :& e :& ... :& en)@
+type (<:) = (:>)
+
 -- | A set of effects @e@ is a subset of itself
 instance e :> e
 
@@ -665,9 +696,9 @@
 subset ::
   forall e1 es m.
   (Monad m) =>
-  (e1 :> es) =>
+  (e1 <: es) =>
   m ()
-subset = satisfied @(e1 :> es)
+subset = satisfied @(e1 <: es)
 
 satisfied :: forall c m. (Monad m, c) => m ()
 satisfied = pure ()
@@ -692,16 +723,16 @@
 -- Right "No exception thrown"
 -- @
 throw ::
-  (e :> es) =>
+  (e <: es) =>
   Exception ex e ->
   -- | Value to throw
   ex ->
   Eff es a
 throw h = case mapHandle h of MkException throw_ -> throw_
 
-has :: forall a b. (a :> b) => a `In` b
+has :: forall a b. (a <: b) => a `In` b
 -- This is safe because, as shown by instanceProof1/2/3, the only way
--- to construct `a :> b` is if `a `In` b`.
+-- to construct `a <: b` is if `a `In` b`.
 has = unsafeInAxiom ZW
 
 data Dict c where
@@ -711,8 +742,8 @@
 unsafeCoerceDict = unsafeCoerce @(Dict c) @(Dict c')
 
 -- Seems like it could be better
-have :: forall a b. a `In` b -> Dict (a :> b)
-have _ = unsafeCoerceDict @(a :> (a :& b)) @(a :> b) Dict
+have :: forall a b. a `In` b -> Dict (a <: b)
+have _ = unsafeCoerceDict @(a <: (a :& b)) @(a <: b) Dict
 
 -- |
 -- @
@@ -791,7 +822,7 @@
 -- @
 rethrowIO ::
   forall ex es e1 e2 r.
-  (e1 :> es, e2 :> es, Control.Exception.Exception ex) =>
+  (e1 <: es, e2 <: es, Control.Exception.Exception ex) =>
   IOE e1 ->
   Exception ex e2 ->
   Eff es r ->
@@ -858,7 +889,7 @@
         (effToIO (useImpl after))
 
 withStateInIO ::
-  (e1 :> es, e2 :> es) =>
+  (e1 <: es, e2 <: es) =>
   IOE e1 ->
   State s e2 ->
   (IORef s -> IO r) ->
@@ -873,7 +904,7 @@
 -- (20,10)
 -- @
 get ::
-  (e :> es) =>
+  (e <: es) =>
   State s e ->
   -- | The current value of the state
   Eff es s
@@ -887,7 +918,7 @@
 -- ((), 30)
 -- @
 put ::
-  (e :> es) =>
+  (e <: es) =>
   State s e ->
   -- | The new value of the state.  The new value is forced before
   -- writing it to the state.
@@ -902,7 +933,7 @@
 -- ((), 20)
 -- @
 modify ::
-  (e :> es) =>
+  (e <: es) =>
   State s e ->
   -- | Apply this function to the state.  The new value of the state
   -- is forced before writing it to the state.
@@ -953,7 +984,7 @@
 -- 15
 -- @
 newState ::
-  (e :> es) =>
+  (e <: es) =>
   StateSource e ->
   -- | The initial value for the state handle
   s ->
@@ -984,7 +1015,7 @@
     pure (a, s')
 
 yieldCoroutine ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Coroutine a b e1 ->
   -- | ͘
   a ->
@@ -1003,7 +1034,7 @@
 -- ([1,2,100], ())
 -- @
 yield ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Stream a e1 ->
   -- | Yield this value from the stream
   a ->
@@ -1062,7 +1093,7 @@
 -- ([1, 2, 100], ())
 -- @
 inFoldable ::
-  (Foldable t, e1 :> es) =>
+  (Foldable t, e1 <: es) =>
   -- | Yield all these values from the stream
   t a ->
   Stream a e1 ->
@@ -1077,7 +1108,7 @@
 -- ([(0, \"A\"), (1, \"B\"), (2, \"C\")], ())
 -- @
 enumerate ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   -- | ͘
   (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
   Stream (Int, a) e2 ->
@@ -1092,7 +1123,7 @@
 -- ([(1, \"A\"), (2, \"B\"), (3, \"C\")], ())
 -- @
 enumerateFrom ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   -- | Initial value
   Int ->
   (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->
@@ -1118,7 +1149,7 @@
   Eff es r
 consumeEach k e = forEach k (\() -> e)
 
-await :: (e :> es) => Consume a e -> Eff es a
+await :: (e <: es) => Consume a e -> Eff es a
 await r = yieldCoroutine r ()
 
 type EarlyReturn = Exception
@@ -1151,7 +1182,7 @@
 -- "Returned early with 5"
 -- @
 returnEarly ::
-  (e :> es) =>
+  (e <: es) =>
   EarlyReturn r e ->
   -- | Return early to the handler, with this value.
   r ->
@@ -1207,15 +1238,15 @@
   Compound h1 h2 (e1 :& e2)
 compound = Compound proxy# proxy#
 
-inComp :: forall a b c r. (a :> b) => (b :> c) => ((a :> c) => r) -> r
+inComp :: forall a b c r. (a <: b) => (b <: c) => ((a <: c) => r) -> r
 inComp k = case have (cmp (has @a @b) (has @b @c)) of Dict -> k
 
 withCompound ::
   forall h1 h2 e es r.
-  (e :> es) =>
+  (e <: es) =>
   Compound h1 h2 e ->
   -- | ͘
-  (forall e1 e2. (e1 :> es, e2 :> es) => h1 e1 -> h2 e2 -> Eff es r) ->
+  (forall e1 e2. (e1 <: es, e2 <: es) => h1 e1 -> h2 e2 -> Eff es r) ->
   Eff es r
 withCompound c f =
   case c of
@@ -1224,27 +1255,27 @@
 
 withC1 ::
   forall e1 e2 ss es r.
-  (ss :> es) =>
+  (ss <: es) =>
   Compound e1 e2 ss ->
-  (forall st. (st :> es) => e1 st -> Eff es r) ->
+  (forall st. (st <: es) => e1 st -> Eff es r) ->
   Eff es r
 withC1 c f = withCompound c (\h _ -> f h)
 
 withC2 ::
   forall e1 e2 ss es r.
-  (ss :> es) =>
+  (ss <: es) =>
   Compound e1 e2 ss ->
-  (forall st. (st :> es) => e2 st -> Eff es r) ->
+  (forall st. (st <: es) => e2 st -> Eff es r) ->
   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 (State 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 (State Int) ss -> Eff es Int
 getC c = withC2 c (\h -> get h)
 
--- TODO: Make this (s1 :> es, s2 :> es), like withC
+-- TODO: Make this (s1 <: es, s2 <: es), like withC
 runCompound ::
   e1 s1 ->
   -- | ͘
@@ -1313,7 +1344,7 @@
     pure (as, r)
 
 mapStream ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   -- | Apply this function to all elements of the input stream.
   (a -> b) ->
   -- | Input stream
@@ -1323,7 +1354,7 @@
 mapStream f = mapMaybe (Just . f)
 
 mapMaybe ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   -- | Yield from the output stream all of the elemnts of the input
   -- stream for which this function returns @Just@
   (a -> Maybe b) ->
@@ -1338,7 +1369,7 @@
 
 -- | Remove 'Nothing' elements from a stream.
 catMaybes ::
-  (e2 :> es) =>
+  (e2 <: es) =>
   -- | Input stream
   (forall e1. Stream (Maybe a) e1 -> Eff (e1 :& es) r) ->
   Stream a e2 ->
@@ -1354,7 +1385,7 @@
 -- ([1,2,3,1,2,3],())
 -- @
 cycleToStream ::
-  (Foldable f, e1 :> es) =>
+  (Foldable f, e1 <: es) =>
   f a ->
   Stream a e1 ->
   -- | ͘
@@ -1371,10 +1402,10 @@
 -- ([1,2,3,4],())
 -- @
 takeConsume ::
-  (e1 :> es, e2 :> es) =>
+  (e1 <: es, e2 <: es) =>
   Int ->
   Consume a e1 ->
-  Stream a e2->
+  Stream a e2 ->
   -- | ͘
   Eff es ()
 takeConsume count source sink = loop count
@@ -1423,13 +1454,13 @@
 -- 15
 -- @
 jumpTo ::
-  (e :> es) =>
+  (e <: es) =>
   Jump e ->
   -- | ͘
   Eff es a
 jumpTo tag = throw tag ()
 
-unwrap :: (e :> es) => Jump e -> Maybe a -> Eff es a
+unwrap :: (e <: es) => Jump e -> Maybe a -> Eff es a
 unwrap j = \case
   Nothing -> jumpTo j
   Just a -> pure a
@@ -1440,7 +1471,7 @@
 
 type role IOE nominal
 
-instance (e :> es) => OneWayCoercible (IOE e) (IOE es) where
+instance (e <: es) => OneWayCoercible (IOE e) (IOE es) where
   oneWayCoercibleImpl = unsafeOneWayCoercible
 
 -- | Run an 'IO' operation in 'Eff'
@@ -1451,7 +1482,7 @@
 -- Hello, world!
 -- @
 effIO ::
-  (e :> es) =>
+  (e <: es) =>
   IOE e ->
   IO a ->
   -- | ͘
@@ -1500,7 +1531,7 @@
   (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) =>
+  (e1 <: es, e2 <: es) =>
   Eff
     es
     ( Either
@@ -1513,7 +1544,7 @@
   forall a b r es.
   (forall e. Coroutine a b e -> Eff (e :& es) r) ->
   forall e.
-  (e :> es) =>
+  (e <: es) =>
   Eff
     es
     ( Either
@@ -1529,7 +1560,7 @@
 newtype Writer w e = Writer (Stream w e)
   deriving (Handle) via OneWayCoercibleHandle (Writer w)
 
-instance (e :> es) => OneWayCoercible (Writer w e) (Writer w es) where
+instance (e <: es) => OneWayCoercible (Writer w e) (Writer w es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 -- |
@@ -1577,7 +1608,7 @@
 -- True
 -- @
 tell ::
-  (e :> es) =>
+  (e <: es) =>
   Writer w e ->
   -- | ͘
   w ->
@@ -1587,7 +1618,7 @@
 newtype Reader r e = MkReader (State r e)
   deriving newtype (Handle)
 
-instance (e :> es) => OneWayCoercible (Reader r e) (Reader r es) where
+instance (e <: es) => OneWayCoercible (Reader r e) (Reader r es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 runReader ::
@@ -1613,7 +1644,7 @@
 --   pure (r, r)
 -- @
 ask ::
-  (e :> es) =>
+  (e <: es) =>
   -- | ͘
   Reader r e ->
   Eff es r
@@ -1621,7 +1652,7 @@
 
 -- | Read the value modified by a function
 asks ::
-  (e :> es) =>
+  (e <: es) =>
   Reader r e ->
   -- | Read the value modified by this function
   (r -> a) ->
@@ -1631,7 +1662,7 @@
 -- | Locally override the value in the @Reader@. It will be restored
 -- when the @local@ block ends.
 local ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Reader r e1 ->
   -- | In the body, the reader value is modified by this function.
   (r -> r) ->
@@ -1657,7 +1688,7 @@
 -- handle via `localHandle`.
 mapHandleReader ::
   forall h e es.
-  (Handle h, e :> es) =>
+  (Handle h, e <: es) =>
   HandleReader h e ->
   -- | ͘
   HandleReader h es
@@ -1667,7 +1698,7 @@
     coerceH = unsafeCoerce (Coercion :: Coercion (h e) (h e))
 
 localHandle ::
-  (e :> es, Handle h) =>
+  (e <: es, Handle h) =>
   HandleReader h e ->
   (h es -> h es) ->
   Eff es r ->
@@ -1682,14 +1713,14 @@
     (\() -> k)
 
 askHandle ::
-  (e :> es, Handle h) =>
+  (e <: es, Handle h) =>
   HandleReader h e ->
   -- | ͘
   Eff es (h es)
 askHandle hh = let UnsafeMkHandleReader st = mapHandle hh in get st
 
 asksHandle ::
-  (e1 :> es, Handle h) =>
+  (e1 <: es, Handle h) =>
   HandleReader h e1 ->
   (forall e. h e -> Eff (e :& es) r) ->
   -- | ͘
@@ -1699,7 +1730,7 @@
   makeOp (k h)
 
 runHandleReader ::
-  (e1 :> es, Handle h) =>
+  (e1 <: es, Handle h) =>
   h e1 ->
   (forall e. HandleReader h e -> Eff (e :& es) r) ->
   -- | ͘
@@ -1719,13 +1750,13 @@
 
     useImplIn k h'
 
-instance (e :> es) => OneWayCoercible (HandleReader h e) (HandleReader h es) where
+instance (e <: es) => OneWayCoercible (HandleReader h e) (HandleReader h es) where
   oneWayCoercibleImpl = unsafeOneWayCoercible
 
 newtype ConstEffect r (e :: Effects) = MkConstEffect r
   deriving (Handle) via OneWayCoercibleHandle (ConstEffect r)
 
-instance (e :> es) => OneWayCoercible (ConstEffect r e) (ConstEffect r es) where
+instance (e <: es) => OneWayCoercible (ConstEffect r e) (ConstEffect r es) where
   oneWayCoercibleImpl = oneWayCoercible
 
 runConstEffect ::
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
@@ -26,7 +26,7 @@
 import GHC.TypeLits (ErrorMessage (Text), TypeError)
 
 withEffToIOCloneHandle ::
-  (e1 :> es, CloneableHandle h) =>
+  (e1 <: es, CloneableHandle h) =>
   IOE e1 ->
   -- | Handle accessible in the continuation
   h es ->
@@ -62,7 +62,7 @@
   oneWayCoercibleImpl = unsafeOneWayCoercible
 
 cloneHandle2 ::
-  (Handle h1, Handle h2, e1 :> es) =>
+  (Handle h1, Handle h2, e1 <: es) =>
   HandleCloner h1 h2 es ->
   h1 e1 ->
   (forall e. h2 e -> Eff (e :& es) r) ->
@@ -108,7 +108,7 @@
   cloneableHandleImpl = MkCloneableHandleD hcHandleReader
 
 cloneHandleClass ::
-  (e1 :> es, CloneableHandle h) =>
+  (e1 <: es, CloneableHandle h) =>
   h e1 ->
   (forall e. h e -> Eff (e :& es) r) ->
   Eff es r
@@ -142,7 +142,7 @@
   handleImpl = handleOneWayCoercible
 
 instance
-  (Handle h1, Handle h2, e :> es) =>
+  (Handle h1, Handle h2, e <: es) =>
   OneWayCoercible
     ((h1 :~> h2) e)
     ((h1 :~> h2) es)
@@ -219,7 +219,7 @@
   deriving newtype (Handle)
 
 instance
-  (Handle h, e :> es) =>
+  (Handle h, e <: es) =>
   OneWayCoercible (GenericCloneableHandle h e) (GenericCloneableHandle h es)
   where
   oneWayCoercibleImpl = oneWayCoercibleTrustMe $ \(MkGenericCloneableHandle h) ->
@@ -259,7 +259,7 @@
 --   deriving ('Bluefin.Compound.Handle') via t'Bluefin.Compound.OneWayCoercibleHandle' MyHandle
 --   deriving ('CloneableHandle') via 'GenericCloneableHandle' MyHandle
 --
--- instance (e t'Bluefin.Eff.:>' es) => t'Bluefin.Compound.OneWayCoercible' (MyHandle e) (MyHandle es) where
+-- instance (e t'Bluefin.Eff.<:' es) => t'Bluefin.Compound.OneWayCoercible' (MyHandle e) (MyHandle es) where
 --   'Bluefin.Compound.oneWayCoercibleImpl' = 'Bluefin.Compound.gOneWayCoercible'
 -- @
 class (Handle h) => CloneableHandle h where
diff --git a/src/Bluefin/Internal/DslBuilderEff.hs b/src/Bluefin/Internal/DslBuilderEff.hs
--- a/src/Bluefin/Internal/DslBuilderEff.hs
+++ b/src/Bluefin/Internal/DslBuilderEff.hs
@@ -15,7 +15,7 @@
   = MkDslBuilderEff {unMkDslBuilderEff :: forall e. h e -> Eff (e :& es) r}
 
 useImplDslBuilderEff ::
-  (e :> es) =>
+  (e <: es) =>
   DslBuilderEff h e r ->
   -- | ͘
   DslBuilderEff h es r
@@ -35,7 +35,7 @@
 dslBuilderEff = MkDslBuilderEff
 
 instance
-  (e :> es) =>
+  (e <: es) =>
   OneWayCoercible (DslBuilderEff h e r) (DslBuilderEff h es r)
   where
   oneWayCoercibleImpl = oneWayCoercible
diff --git a/src/Bluefin/Internal/DslBuilderEffects.hs b/src/Bluefin/Internal/DslBuilderEffects.hs
--- a/src/Bluefin/Internal/DslBuilderEffects.hs
+++ b/src/Bluefin/Internal/DslBuilderEffects.hs
@@ -17,7 +17,7 @@
 newtype DslBuilderEffects h es r
   = MkDslBuilderEffects {unMkDslBuilderEffects :: forall e. h e -> Eff (e :& es) r}
 
-useImplDslBuilderEffects :: (e :> es) => DslBuilderEffects h e r -> DslBuilderEffects h es r
+useImplDslBuilderEffects :: (e <: es) => DslBuilderEffects h e r -> DslBuilderEffects h es r
 useImplDslBuilderEffects = oneWayCoerce
 
 runDslBuilderEffects :: h es -> DslBuilderEffects h es r -> Eff es r
@@ -27,7 +27,7 @@
 dslBuilderEffects = MkDslBuilderEffects
 
 instance
-  (e :> es) =>
+  (e <: es) =>
   OneWayCoercible (DslBuilderEffects h e r) (DslBuilderEffects h es r)
   where
   oneWayCoercibleImpl = oneWayCoercible
diff --git a/src/Bluefin/Internal/Examples.hs b/src/Bluefin/Internal/Examples.hs
--- a/src/Bluefin/Internal/Examples.hs
+++ b/src/Bluefin/Internal/Examples.hs
@@ -206,7 +206,7 @@
   forEach formattedLines $ \line -> effIO io (putStrLn line)
 
 awaitList ::
-  (e :> es) =>
+  (e <: es) =>
   [a] ->
   IOE e ->
   (forall e1. Consume a e1 -> Eff (e1 :& es) ()) ->
@@ -226,7 +226,7 @@
           pure x
 
 takeRec ::
-  (e3 :> es) =>
+  (e3 <: es) =>
   Int ->
   (forall e. Consume a e -> Eff (e :& es) ()) ->
   Consume a e3 ->
@@ -241,7 +241,7 @@
         await rec
 
 mapRec ::
-  (e :> es) =>
+  (e <: es) =>
   (a -> b) ->
   (forall e1. Consume b e1 -> Eff (e1 :& es) ()) ->
   Consume a e ->
@@ -249,7 +249,7 @@
 mapRec f = traverseRec (pure . f)
 
 traverseRec ::
-  (e :> es) =>
+  (e <: es) =>
   (a -> Eff es b) ->
   (forall e1. Consume b e1 -> Eff (e1 :& es) ()) ->
   Consume a e ->
@@ -259,7 +259,7 @@
   f r
 
 awaitUsage ::
-  (e1 :> es, e2 :> es) =>
+  (e1 <: es, e2 <: es) =>
   IOE e1 ->
   (forall e. Consume () e -> Eff (e :& es) ()) ->
   Consume Int e2 ->
@@ -424,10 +424,10 @@
 
 type MyHandle = Compound (State Int) (Exception String)
 
-myInc :: (e :> es) => MyHandle e -> Eff es ()
+myInc :: (e <: es) => MyHandle e -> Eff es ()
 myInc h = withCompound h (\s _ -> modify s (+ 1))
 
-myBail :: (e :> es) => MyHandle e -> Eff es r
+myBail :: (e <: es) => MyHandle e -> Eff es r
 myBail h = withCompound h $ \s e -> do
   i <- get s
   throw e ("Current state was: " ++ show i)
@@ -485,7 +485,7 @@
   get total
 
 incrementReadLine ::
-  (e1 :> es, e2 :> es, e3 :> es) =>
+  (e1 <: es, e2 <: es, e3 <: es) =>
   State Int e1 ->
   Exception String e2 ->
   IOE e3 ->
@@ -515,7 +515,7 @@
 
 newtype Counter1 e = MkCounter1 (State Int e)
 
-incCounter1 :: (e :> es) => Counter1 e -> Eff es ()
+incCounter1 :: (e <: es) => Counter1 e -> Eff es ()
 incCounter1 (MkCounter1 st) = modify st (+ 1)
 
 runCounter1 ::
@@ -539,7 +539,7 @@
 
 data Counter2 e1 e2 = MkCounter2 (State Int e1) (Exception () e2)
 
-incCounter2 :: (e1 :> es, e2 :> es) => Counter2 e1 e2 -> Eff es ()
+incCounter2 :: (e1 <: es, e2 <: es) => Counter2 e1 e2 -> Eff es ()
 incCounter2 (MkCounter2 st ex) = do
   count <- get st
   when (count >= 10) $
@@ -567,7 +567,7 @@
 
 data Counter3 e = MkCounter3 (State Int e) (Exception () e)
 
-incCounter3 :: (e :> es) => Counter3 e -> Eff es ()
+incCounter3 :: (e <: es) => Counter3 e -> Eff es ()
 incCounter3 (MkCounter3 st ex) = do
   count <- get st
   when (count >= 10) $
@@ -595,12 +595,12 @@
 
 newtype Counter3B e = MkCounter3B (IOE e)
 
-incCounter3B :: (e :> es) => Counter3B e -> Eff es ()
+incCounter3B :: (e <: es) => Counter3B e -> Eff es ()
 incCounter3B (MkCounter3B io) =
   effIO io (putStrLn "You tried to increment the counter")
 
 runCounter3B ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   IOE e1 ->
   (forall e. Counter3B e -> Eff (e :& es) r) ->
   Eff es r
@@ -622,7 +622,7 @@
 data Counter4 e
   = MkCounter4 (State Int e) (Exception () e) (Stream String e)
 
-incCounter4 :: (e :> es) => Counter4 e -> Eff es ()
+incCounter4 :: (e <: es) => Counter4 e -> Eff es ()
 incCounter4 (MkCounter4 st ex y) = do
   count <- get st
 
@@ -634,13 +634,13 @@
 
   put st (count + 1)
 
-getCounter4 :: (e :> es) => Counter4 e -> String -> Eff es Int
+getCounter4 :: (e <: es) => Counter4 e -> String -> Eff es Int
 getCounter4 (MkCounter4 st _ y) msg = do
   yield y msg
   get st
 
 runCounter4 ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Stream String e1 ->
   (forall e. Counter4 e -> Eff (e :& es) r) ->
   Eff es Int
@@ -671,17 +671,17 @@
   deriving (Generic)
   deriving (Handle) via OneWayCoercibleHandle Counter5
 
-instance (e :> es) => OneWayCoercible (Counter5 e) (Counter5 es) where
+instance (e <: es) => OneWayCoercible (Counter5 e) (Counter5 es) where
   oneWayCoercibleImpl = gOneWayCoercible
 
-incCounter5 :: (e :> es) => Counter5 e -> Eff es ()
+incCounter5 :: (e <: es) => Counter5 e -> Eff es ()
 incCounter5 e = incCounter5Impl (mapHandle e)
 
-getCounter5 :: (e :> es) => Counter5 e -> String -> Eff es Int
+getCounter5 :: (e <: es) => Counter5 e -> String -> Eff es Int
 getCounter5 e msg = getCounter5Impl (mapHandle e) msg
 
 runCounter5 ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Stream String e1 ->
   (forall e. Counter5 e -> Eff (e :& es) r) ->
   Eff es Int
@@ -730,19 +730,19 @@
   deriving (Generic)
   deriving (Handle) via OneWayCoercibleHandle Counter6
 
-instance (e :> es) => OneWayCoercible (Counter6 e) (Counter6 es) where
+instance (e <: es) => OneWayCoercible (Counter6 e) (Counter6 es) where
   oneWayCoercibleImpl = gOneWayCoercible
 
-incCounter6 :: (e :> es) => Counter6 e -> Eff es ()
+incCounter6 :: (e <: es) => Counter6 e -> Eff es ()
 incCounter6 e = incCounter6Impl (mapHandle e)
 
-getCounter6 :: (e :> es) => Counter6 e -> String -> Eff es Int
+getCounter6 :: (e <: es) => Counter6 e -> String -> Eff es Int
 getCounter6 (MkCounter6 _ st y) msg = do
   yield y msg
   get st
 
 runCounter6 ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Stream String e1 ->
   (forall e. Counter6 e -> Eff (e :& es) r) ->
   Eff es Int
@@ -792,7 +792,7 @@
 -- | The "forall" in the type of @incCounter7@ means that we can't
 -- derive the @OneWayCoercible@ instance with 'gOneWayCoercible' so
 -- instead we use @oneWayCoercibleTrustMe@.
-instance (e :> es) => OneWayCoercible (Counter7 e) (Counter7 es) where
+instance (e <: es) => OneWayCoercible (Counter7 e) (Counter7 es) where
   oneWayCoercibleImpl = oneWayCoercibleTrustMe $ \c ->
     MkCounter7
       { incCounter7Impl = \ex -> useImplUnder (incCounter7Impl c ex),
@@ -801,16 +801,16 @@
       }
 
 incCounter7 ::
-  (e :> es, e1 :> es) => Counter7 e -> Exception () e1 -> Eff es ()
+  (e <: es, e1 <: es) => Counter7 e -> Exception () e1 -> Eff es ()
 incCounter7 e ex = makeOp (incCounter7Impl (mapHandle e) (mapHandle ex))
 
-getCounter7 :: (e :> es) => Counter7 e -> String -> Eff es Int
+getCounter7 :: (e <: es) => Counter7 e -> String -> Eff es Int
 getCounter7 (MkCounter7 _ st y) msg = do
   yield y msg
   get st
 
 runCounter7 ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Stream String e1 ->
   (forall e. Counter7 e -> Eff (e :& es) r) ->
   Eff es Int
@@ -867,18 +867,18 @@
   deriving (Generic)
   deriving (Handle) via OneWayCoercibleHandle FileSystem
 
-instance (e :> es) => OneWayCoercible (FileSystem e) (FileSystem es) where
+instance (e <: es) => OneWayCoercible (FileSystem e) (FileSystem es) where
   oneWayCoercibleImpl = gOneWayCoercible
 
-readFile :: (e :> es) => FileSystem e -> FilePath -> Eff es String
+readFile :: (e <: es) => FileSystem e -> FilePath -> Eff es String
 readFile fs filepath = readFileImpl (mapHandle fs) filepath
 
-writeFile :: (e :> es) => FileSystem e -> FilePath -> String -> Eff es ()
+writeFile :: (e <: es) => FileSystem e -> FilePath -> String -> Eff es ()
 writeFile fs filepath contents =
   writeFileImpl (mapHandle fs) filepath contents
 
 runFileSystemPure ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Exception String e1 ->
   [(FilePath, String)] ->
   (forall e2. FileSystem e2 -> Eff (e2 :& es) r) ->
@@ -900,7 +900,7 @@
 
 runFileSystemIO ::
   forall e1 e2 es r.
-  (e1 :> es, e2 :> es) =>
+  (e1 <: es, e2 <: es) =>
   Exception String e1 ->
   IOE e2 ->
   (forall e. FileSystem e -> Eff (e :& es) r) ->
@@ -915,13 +915,13 @@
           \path -> adapt . Prelude.writeFile path
       }
   where
-    adapt :: (e1 :> ess, e2 :> ess) => IO a -> Eff ess a
+    adapt :: (e1 <: ess, e2 <: ess) => IO a -> Eff ess a
     adapt m =
       effIO io (Control.Exception.try @IOException m) >>= \case
         Left e -> throw ex (show e)
         Right r -> pure r
 
-action :: (e :> es) => FileSystem e -> Eff es String
+action :: (e <: es) => FileSystem e -> Eff es String
 action fs = do
   file <- readFile fs "/dev/null"
   when (length file == 0) $ do
@@ -954,14 +954,14 @@
   deriving (Generic)
   deriving (Handle) via OneWayCoercibleHandle Application
 
-instance (e :> es) => OneWayCoercible (Application e) (Application es) where
+instance (e <: es) => OneWayCoercible (Application e) (Application es) where
   oneWayCoercibleImpl = gOneWayCoercible
 
 -- This example shows a case where we can use @bracket@ polymorphically
 -- in order to perform correct cleanup if @es@ is instantiated to a
 -- set of effects that includes exceptions.
 polymorphicBracket ::
-  (st :> es) =>
+  (st <: es) =>
   State (Integer, Bool) st ->
   Eff es () ->
   Eff es ()
@@ -990,7 +990,7 @@
 pipesExample1 :: IO ()
 pipesExample1 = runEff_ $ \io -> runEffect (count >-> P.print io)
   where
-    count :: (e :> es) => Producer Int e -> Eff es ()
+    count :: (e <: es) => Producer Int e -> Eff es ()
     count p = for_ [1 .. 5] $ \i -> P.yield p i
 
 pipesExample2 :: IO String
@@ -1046,7 +1046,7 @@
   deriving (Handle) via OneWayCoercibleHandle (DynamicReader r)
 
 instance
-  (e :> es) =>
+  (e <: es) =>
   OneWayCoercible (DynamicReader r e) (DynamicReader r es)
   where
   oneWayCoercibleImpl = oneWayCoercibleTrustMe $ \h ->
@@ -1056,13 +1056,13 @@
       }
 
 askLR ::
-  (e :> es) =>
+  (e <: es) =>
   DynamicReader r e ->
   Eff es r
 askLR c = askLRImpl (mapHandle c)
 
 localLR ::
-  (e :> es) =>
+  (e <: es) =>
   DynamicReader r e ->
   (r -> r) ->
   Eff es a ->
@@ -1082,21 +1082,21 @@
           localLRImpl = \f k' -> local h f (useImpl k')
         }
 
--- Fails to compile unless '(e :> es) => e :> (x :& es)' is incoherent
+-- Fails to compile unless '(e <: es) => e <: (x :& es)' is incoherent
 -- (otherwise I guess it "commits to it too soon")
 example :: ()
 example = runPureEff $
   evalState () $ \st1 ->
     evalState () $ \st2 -> do
       Proxy :: Proxy es <- effTag
-      satisfied @(es :> es)
+      satisfied @(es <: es)
 
       Proxy :: Proxy e1 <- handleTag st1
       Proxy :: Proxy e2 <- handleTag st2
 
-      satisfied @(e1 :> e1)
-      satisfied @(e2 :> e2)
-      satisfied @(e1 :> (e1 :& e2))
-      satisfied @(e2 :> (e1 :& e2))
+      satisfied @(e1 <: e1)
+      satisfied @(e2 <: e2)
+      satisfied @(e1 <: (e1 :& e2))
+      satisfied @(e2 <: (e1 :& e2))
 
-      satisfied @((e1 :& e2) :> (e1 :& e2))
+      satisfied @((e1 :& e2) <: (e1 :& e2))
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
@@ -73,13 +73,13 @@
   handleImpl = handleOneWayCoercible
 
 instance
-  (Handle h, e :> es) =>
+  (Handle h, e <: es) =>
   OneWayCoercible (MakeExceptions r a h e) (MakeExceptions r a h es)
   where
   oneWayCoercibleImpl = unsafeOneWayCoercible
 
 instance
-  (Handle h, e :> es) =>
+  (Handle h, e <: es) =>
   OneWayCoercible (HandlerUnwrapped r a h e) (HandlerUnwrapped r a h es)
   where
   oneWayCoercibleImpl = unsafeOneWayCoercible
@@ -226,7 +226,7 @@
   deriving (Generic)
 
 instance
-  (e :> es) =>
+  (e <: es) =>
   OneWayCoercible
     (BracketBase bodyRes r a e)
     (BracketBase bodyRes r a es)
@@ -234,7 +234,7 @@
   oneWayCoercibleImpl = gOneWayCoercible
 
 useImplBracketBase ::
-  (e :> es) =>
+  (e <: es) =>
   BracketBase b r a e ->
   BracketBase b r a es
 useImplBracketBase = oneWayCoerce
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
@@ -14,7 +14,7 @@
     useImplIn,
     useImplUnder,
     (:&),
-    (:>),
+    type (<:),
   )
 import Bluefin.Internal.OneWayCoercible (OneWayCoercible (oneWayCoercibleImpl), OneWayCoercibleD)
 import Data.Kind (Type)
@@ -31,7 +31,7 @@
 -- usages provided for people who are migrating from those libraries.
 type Effect = (Type -> Type) -> Type -> Type
 
-instance (e :> es) => OneWayCoercible (Send f e) (Send f es) where
+instance (e <: es) => OneWayCoercible (Send f e) (Send f es) where
   oneWayCoercibleImpl =
     oneWayCoercibleTrustMe (\(MkSend g) -> MkSend (useImplUnder . g))
 
@@ -41,7 +41,7 @@
 -- and @polysemy@'s
 -- [@send@](https://hackage.haskell.org/package/polysemy/docs/Polysemy.html#v:send).
 send ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Send f e1 ->
   -- | Handle this operation using the effect handler currently in
   -- scope for the @Send f@ handle.
@@ -66,7 +66,7 @@
 --
 -- runFileSystem ::
 --   forall es e1 e2 r.
---   (e1 :> es, e2 :> es) =>
+--   (e1 \<: es, e2 \<: es) =>
 --   t'Bluefin.IO.IOE' e1 ->
 --   t'Bluefin.Exception.Exception' t'Control.Exception.IOException' e2 ->
 --   (forall e. 'Send' FileSystem e -> Eff (e :& es) r) ->
@@ -84,7 +84,7 @@
 --   where
 --     -- If you don't want to write this signature you can use
 --     -- {-# LANGUAGE NoMonoLocalBinds #-}
---     adapt :: (e1 :> es', e2 :> es') => IO r' -> Eff es' r'
+--     adapt :: (e1 \<: es', e2 \<: es') => IO r' -> Eff es' r'
 --     adapt m = 'Bluefin.IO.rethrowIO' io ex (effIO io m)
 -- @
 interpret ::
@@ -107,7 +107,7 @@
 -- |
 -- @
 -- instance
---   (e :> es) =>
+--   (e \<: es) =>
 --   t'Bluefin.Compound.OneWayCoercible' ('GadtEffect' FileSystem r e) (GadtEffect FileSystem r es)
 --   where
 --   'Bluefin.Compound.oneWayCoercibleImpl' = 'oneWayCoercibleGadtEffectTrustMe' $ \\case
@@ -116,8 +116,8 @@
 --     Trace msg body -> Trace msg (useImpl body)
 -- @
 oneWayCoercibleGadtEffectTrustMe ::
-  (e :> es) =>
-  (forall e' es'. (e' :> es') => f (Eff e') r -> f (Eff es') r) ->
+  (e <: es) =>
+  (forall e' es'. (e' <: es') => f (Eff e') r -> f (Eff es') r) ->
   -- | ͘
   OneWayCoercibleD (GadtEffect f r e) (GadtEffect f r es)
 oneWayCoercibleGadtEffectTrustMe k = oneWayCoercibleTrustMe (mapGadtEffect k)
@@ -126,7 +126,7 @@
 --
 -- @
 -- augmentOp2Interpose ::
---   (e1 :> es, e2 :> es) =>
+--   (e1 \<: es, e2 \<: es) =>
 --   IOE e2 ->
 --   t'Bluefin.HandleReader.HandleReader' (Send E) e1 ->
 --   Eff es r ->
@@ -136,7 +136,7 @@
 --   op -> 'passthrough' fc op
 -- @
 passthrough ::
-  (Handle (GadtEffect f r), e1 :> es, e2 :> es) =>
+  (Handle (GadtEffect f r), e1 <: es, e2 <: es) =>
   Send f e1 ->
   f (Eff e2) r ->
   -- | ͘
@@ -146,7 +146,7 @@
 -- |
 -- @
 -- augmentOp2Interpose ::
---   (e1 :> es, e2 :> es) =>
+--   (e1 \<: es, e2 \<: es) =>
 --   IOE e2 ->
 --   t'Bluefin.HandleReader.HandleReader' (Send E) e1 ->
 --   Eff es r ->
@@ -156,7 +156,7 @@
 --   op -> 'passthrough' fc op
 -- @
 interpose ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   -- | Reimplementation of effect handler for @Send f@ in terms of the
   -- the original effect handler, which is passed as the argument
   (Send f es -> EffectHandler f es) ->
diff --git a/src/Bluefin/Internal/Pipes.hs b/src/Bluefin/Internal/Pipes.hs
--- a/src/Bluefin/Internal/Pipes.hs
+++ b/src/Bluefin/Internal/Pipes.hs
@@ -17,7 +17,7 @@
     withEarlyReturn,
     yieldCoroutine,
     (:&),
-    (:>),
+    type (<:),
   )
 import Bluefin.Internal qualified
 import Control.Monad (forever)
@@ -39,7 +39,7 @@
 infixl 7 >->
 
 (>->) ::
-  (e1 :> es) =>
+  (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 ->
@@ -53,7 +53,7 @@
 infixr 7 <-<
 
 (<-<) ::
-  (e1 :> es) =>
+  (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 ->
@@ -62,7 +62,7 @@
 k1 <-< k2 = k2 >-> k1
 
 for ::
-  (e1 :> es) =>
+  (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 ->
@@ -75,7 +75,7 @@
 infixr 4 ~>
 
 (~>) ::
-  (e1 :> es) =>
+  (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 ->
@@ -87,7 +87,7 @@
 infixl 4 <~
 
 (<~) ::
-  (e1 :> es) =>
+  (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 ->
@@ -102,7 +102,7 @@
 infixl 5 >~
 
 (>~) ::
-  (e1 :> es) =>
+  (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 ->
@@ -119,7 +119,7 @@
 infixr 5 ~<
 
 (~<) ::
-  (e1 :> es) =>
+  (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 ->
@@ -150,14 +150,14 @@
     absurd
 
 yield ::
-  (e :> es) =>
+  (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 :: (e <: es) => Proxy () a y' y e -> Eff es a
 await (MkProxy c _) = yieldCoroutine c ()
 
 -- | @pipe@'s 'next' doesn't exist in Bluefin
@@ -173,7 +173,7 @@
 each f p = for_ f (yield p)
 
 repeatM ::
-  (e :> es) =>
+  (e <: es) =>
   Eff es a ->
   Proxy x' x () a e ->
   -- | ͘
@@ -183,7 +183,7 @@
   yield p a
 
 replicateM ::
-  (e :> es) =>
+  (e <: es) =>
   Int ->
   Eff es a ->
   Proxy x' x () a e ->
@@ -194,7 +194,7 @@
   yield p a
 
 print ::
-  (e2 :> es, e1 :> es, Show a) =>
+  (e2 <: es, e1 <: es, Show a) =>
   IOE e1 ->
   Consumer a e2 ->
   -- | ͘
@@ -204,7 +204,7 @@
   effIO io (Prelude.print a)
 
 unfoldr ::
-  (e :> es) =>
+  (e <: es) =>
   (s -> Eff es (Either r (a, s))) ->
   s ->
   Proxy x1 x () a e ->
@@ -220,7 +220,7 @@
         yield p a
 
 mapM_ ::
-  (e :> es) =>
+  (e <: es) =>
   (a -> Eff es ()) ->
   Proxy () a b b' e ->
   -- | ͘
@@ -228,14 +228,14 @@
 mapM_ f = for cat (\a _ -> useImpl (f a))
 
 drain ::
-  (e :> es) =>
+  (e <: es) =>
   Proxy () b c' c e ->
   -- | ͘
   Eff es r
 drain = for cat (\_ _ -> pure ())
 
 map ::
-  (e :> es) =>
+  (e <: es) =>
   (a -> b) ->
   Pipe a b e ->
   -- | ͘
@@ -243,7 +243,7 @@
 map f = for cat (\a p1 -> yield p1 (f a))
 
 mapM ::
-  (e :> es) =>
+  (e <: es) =>
   (a -> Eff es b) ->
   Pipe a b e ->
   -- | ͘
@@ -253,7 +253,7 @@
   yield p b_
 
 takeWhile' ::
-  (e :> es) =>
+  (e <: es) =>
   (r -> Bool) ->
   Pipe r r e ->
   -- | ͘
@@ -265,7 +265,7 @@
     else returnEarly early a
 
 stdinLn ::
-  (e1 :> es, e2 :> es) =>
+  (e1 <: es, e2 <: es) =>
   IOE e1 ->
   Producer String e2 ->
   -- | ͘
@@ -275,7 +275,7 @@
   yield c line
 
 stdoutLn ::
-  (e1 :> es, e2 :> es) =>
+  (e1 <: es, e2 <: es) =>
   IOE e1 ->
   Consumer String e2 ->
   -- | ͘
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
@@ -15,7 +15,7 @@
 
 data PrimStateEff (es :: Effects)
 
-instance (e :> es) => OneWayCoercible (Prim e) (Prim es) where
+instance (e <: es) => OneWayCoercible (Prim e) (Prim es) where
   oneWayCoercibleImpl = unsafeOneWayCoercible
 
 runPrim ::
@@ -25,7 +25,7 @@
 runPrim k = makeOp (k UnsafeMkPrim)
 
 primitive ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Prim e1 ->
   (State# (PrimStateEff e1) -> (# State# (PrimStateEff e1), a #)) ->
   -- | ͘
diff --git a/src/Bluefin/Internal/System/IO.hs b/src/Bluefin/Internal/System/IO.hs
--- a/src/Bluefin/Internal/System/IO.hs
+++ b/src/Bluefin/Internal/System/IO.hs
@@ -15,7 +15,7 @@
     oneWayCoercibleTrustMe,
     useImplIn,
     (:&),
-    (:>),
+    type (<:),
   )
 import Bluefin.Internal qualified
 import Bluefin.Internal.OneWayCoercible (OneWayCoercible (oneWayCoercibleImpl))
@@ -28,12 +28,12 @@
     (Bluefin.Internal.Handle)
     via Bluefin.Internal.OneWayCoercibleHandle Handle
 
-instance (e :> es) => OneWayCoercible (Handle e) (Handle es) where
+instance (e <: es) => OneWayCoercible (Handle e) (Handle es) where
   oneWayCoercibleImpl = oneWayCoercibleTrustMe $ \(UnsafeMkHandle h io) ->
     UnsafeMkHandle h (mapHandle io)
 
 withFile ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   IOE e1 ->
   FilePath ->
   System.IO.IOMode ->
@@ -50,7 +50,7 @@
     )
 
 hPutChar ::
-  (e :> es) =>
+  (e <: es) =>
   Handle e ->
   Char ->
   -- | ͘
@@ -58,7 +58,7 @@
 hPutChar h = unsafeWithHandle h . flip System.IO.hPutChar
 
 hPutStr ::
-  (e :> es) =>
+  (e <: es) =>
   Handle e ->
   String ->
   -- | ͘
@@ -66,7 +66,7 @@
 hPutStr h = unsafeWithHandle h . flip System.IO.hPutStr
 
 hPutStrLn ::
-  (e :> es) =>
+  (e <: es) =>
   Handle e ->
   String ->
   -- | ͘
@@ -74,21 +74,21 @@
 hPutStrLn h = unsafeWithHandle h . flip System.IO.hPutStrLn
 
 hFlush ::
-  (e :> es) =>
+  (e <: es) =>
   Handle e ->
   -- | ͘
   Eff es ()
 hFlush h = unsafeWithHandle h System.IO.hFlush
 
 hGetLine ::
-  (e :> es) =>
+  (e <: es) =>
   Handle e ->
   -- | ͘
   Eff es String
 hGetLine h = unsafeWithHandle h System.IO.hGetLine
 
 hIsEOF ::
-  (e :> es) =>
+  (e <: es) =>
   Handle e ->
   -- | ͘
   Eff es Bool
@@ -99,7 +99,7 @@
 -- issue](https://github.com/tomjaguarpaw/bluefin/issues/new) to
 -- request it be added.  In the meantime you can define it yourself with @unsafeWithHandle@.
 unsafeWithHandle ::
-  (e1 :> es) =>
+  (e1 <: es) =>
   Handle e1 ->
   (System.IO.Handle -> IO r) ->
   Eff es r
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -4,7 +4,7 @@
 module Main (main) where
 
 import Bluefin.Internal
-import Control.Monad (when)
+import Control.Monad (forever, when)
 import Data.Foldable (for_)
 import Test.GeneralBracket (test_generalBracket)
 import Test.SpecH (SpecH, assertEqual, runSpecH)
@@ -37,6 +37,7 @@
 
     test_localInHandler y
     test_generalBracket io y
+    test_streamConsumeReader y
 
 (!?) :: [a] -> Int -> Maybe a
 xs !? i = runPureEff $
@@ -63,13 +64,13 @@
                 jumpTo break
 
 -- | Inverse to 'try'
-eitherEff :: (e1 :> es) => Either e r -> Exception e e1 -> Eff es r
+eitherEff :: (e1 <: es) => Either e r -> Exception e e1 -> Eff es r
 eitherEff eith ex = case eith of
   Left e -> throw ex e
   Right r -> pure r
 
 -- | Inverse to 'runState'
-stateEff :: (e1 :> es) => (s -> (a, s)) -> State s e1 -> Eff es a
+stateEff :: (e1 <: es) => (s -> (a, s)) -> State s e1 -> Eff es a
 stateEff f st = do
   s <- get st
   let (a, s') = f s
@@ -77,13 +78,56 @@
   pure a
 
 -- | Inverse to 'yieldToList'
-listEff :: (e1 :> es) => ([a], r) -> Stream a e1 -> Eff es r
+listEff :: (e1 <: es) => ([a], r) -> Stream a e1 -> Eff es r
 listEff (as, r) y = do
   for_ as (yield y)
   pure r
 
-test_localInHandler :: (e :> es) => SpecH e -> Eff es ()
+test_localInHandler :: (e <: es) => SpecH e -> Eff es ()
 test_localInHandler y = runReader "global" $ \re ->
   forEach
     (\y2 -> local re (const "local") (yield y2 ()))
     (\() -> assertEqual y "Reader local" "local" =<< ask re)
+
+-- This test confirms the buggy behavior reported in
+--
+--    https://github.com/tomjaguarpaw/bluefin/issues/98
+test_streamConsumeReader :: (e <: es) => SpecH e -> Eff es ()
+test_streamConsumeReader spech = do
+  runReader @Int 0 $ \r -> do
+    streamConsume
+      ( \y -> do
+          let s = yield y ()
+          let check i = assertEqual spech "Reader local" i =<< ask r
+          check 0
+          s
+          check (-100) -- Should be 0
+          s
+          check (-200) -- Should be 0
+          local r (+ 1) $ do
+            check (-199) -- Should be 1
+            s
+            check (-299) -- Should be 1
+            local r (+ 1) $ do
+              check (-298) -- Should be 2
+              s
+              check (-398) -- Should be 2
+            check (-299) -- Should be 1
+            s
+            check (-299) -- Should be 1
+          check (-200) -- Should be 0
+          s
+          check (-200) -- Should be 0
+      )
+      ( \a -> do
+          let p = await a
+          p
+          local r (subtract 100) $ do
+            p
+            local r (subtract 100) $ do
+              p
+              local r (subtract 100) $ do
+                p
+                local r (subtract 100) $ do
+                  forever p
+      )
diff --git a/test/Test/GeneralBracket.hs b/test/Test/GeneralBracket.hs
--- a/test/Test/GeneralBracket.hs
+++ b/test/Test/GeneralBracket.hs
@@ -9,7 +9,7 @@
 import Control.Exception (ErrorCall)
 import Test.SpecH (SpecH, assertEqual)
 
-test_generalBracket :: (e1 :> es, e2 :> es) => IOE e1 -> SpecH e2 -> Eff es ()
+test_generalBracket :: (e1 <: es, e2 <: es) => IOE e1 -> SpecH e2 -> Eff es ()
 test_generalBracket io s = do
   (actual, ()) <- yieldToList $ \y -> example io y
 
@@ -23,12 +23,12 @@
   deriving (Generic)
   deriving (Handle) via OneWayCoercibleHandle ThreeExceptions
 
-instance (e :> es) => OneWayCoercible (ThreeExceptions e) (ThreeExceptions es) where
+instance (e <: es) => OneWayCoercible (ThreeExceptions e) (ThreeExceptions es) where
   oneWayCoercibleImpl = gOneWayCoercible
 
 threeExceptionsMakeExceptions ::
   forall es e1.
-  (e1 :> es) =>
+  (e1 <: es) =>
   Stream String e1 ->
   MakeExceptions String () ThreeExceptions es
 threeExceptionsMakeExceptions y =
@@ -48,7 +48,7 @@
 
 example ::
   forall es e1 e2.
-  (e1 :> es, e2 :> es) =>
+  (e1 <: es, e2 <: es) =>
   IOE e1 ->
   Stream String e2 ->
   Eff es ()
@@ -71,7 +71,7 @@
     -- If you want to avoid writing this signature use
     --  NoMonoLocalBinds and NoMonomorphismRestriction
     g ::
-      (e2 :> es') =>
+      (e2 <: es') =>
       ( forall e. ThreeExceptions e -> String -> Eff (e :& es') r
       ) ->
       Eff es' ()
diff --git a/test/Test/SpecH.hs b/test/Test/SpecH.hs
--- a/test/Test/SpecH.hs
+++ b/test/Test/SpecH.hs
@@ -11,7 +11,7 @@
 type SpecH = Stream (String, Maybe (SpecInfo ()))
 
 assertEqual ::
-  (e :> es, Eq a, Show a) => SpecH e -> String -> a -> a -> Eff es ()
+  (e <: es, Eq a, Show a) => SpecH e -> String -> a -> a -> Eff es ()
 assertEqual y n c1 c2 =
   yield
     y
@@ -27,7 +27,7 @@
 
 runTests ::
   forall es e3.
-  (e3 :> es) =>
+  (e3 <: es) =>
   (forall e1. SpecH e1 -> Eff (e1 :& es) ()) ->
   Stream String e3 ->
   Eff es Bool
@@ -55,7 +55,7 @@
   pure passedAll
 
 runSpecH ::
-  (e :> es) =>
+  (e <: es) =>
   IOE e ->
   (forall e1. SpecH e1 -> Eff (e1 :& es) ()) ->
   Eff es ()
