diff --git a/data-effects-core.cabal b/data-effects-core.cabal
--- a/data-effects-core.cabal
+++ b/data-effects-core.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               data-effects-core
-version:            0.4.0.2
+version:            0.4.1.0
 
 -- A short (one-line) description of the package.
 synopsis: A basic framework for effect systems based on effects represented by GADTs.
@@ -37,7 +37,7 @@
 source-repository head
     type: git
     location: https://github.com/sayo-hs/data-effects
-    tag: v0.4.0.2
+    tag: v0.4.1.0
     subdir: data-effects-core
 
 library
diff --git a/src/Data/Effect.hs b/src/Data/Effect.hs
--- a/src/Data/Effect.hs
+++ b/src/Data/Effect.hs
@@ -35,6 +35,9 @@
     ) =>
     FirstOrder (e :: Effect)
 
+-- | A higher-order polynomial functor.
+class PolyHFunctor (e :: Effect)
+
 -- * Nop Effect
 
 -- | A effect with no operations.
@@ -47,6 +50,7 @@
 instance HFunctor Nop where
     hfmap _ = \case {}
     {-# INLINE hfmap #-}
+instance PolyHFunctor Nop
 
 -- * Embedding Effect
 
@@ -61,6 +65,7 @@
 instance HFunctor (Emb e) where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor (Emb e)
 
 newtype Unemb e a = Unemb {getUnemb :: forall f. e f a}
 
@@ -78,6 +83,7 @@
 instance HFunctor (Ask r) where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor (Ask r)
 
 -- | An effect that locally modifies the value held in the environment.
 data Local r :: Effect where
@@ -95,6 +101,7 @@
 instance HFunctor (Local r) where
     hfmap phi (Local f a) = Local f (phi a)
     {-# INLINE hfmap #-}
+instance PolyHFunctor (Local r)
 
 -- * State Effect
 
@@ -112,6 +119,7 @@
 instance HFunctor (State s) where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor (State s)
 
 -- * Writer Effects
 
@@ -127,6 +135,7 @@
 instance HFunctor (Tell w) where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor (Tell w)
 
 -- | An effect that performs local operations on accumulations in the context on a per-scope basis.
 data WriterH w :: Effect where
@@ -151,6 +160,7 @@
         Listen a -> Listen $ phi a
         Censor f a -> Censor f (phi a)
     {-# INLINE hfmap #-}
+instance PolyHFunctor (WriterH w)
 
 -- * Exception Effects
 
@@ -166,6 +176,7 @@
 instance HFunctor (Throw e) where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor (Throw e)
 
 -- | An effect to catch exceptions.
 data Catch e :: Effect where
@@ -178,11 +189,12 @@
         -> Catch e f a
 
 data CatchLabel
-type instance LabelOf (Catch w) = CatchLabel
-type instance OrderOf (Catch w) = 'HigherOrder
-instance HFunctor (Catch w) where
+type instance LabelOf (Catch e) = CatchLabel
+type instance OrderOf (Catch e) = 'HigherOrder
+instance HFunctor (Catch e) where
     hfmap phi (Catch a hdl) = Catch (phi a) (phi . hdl)
     {-# INLINE hfmap #-}
+instance PolyHFunctor (Catch e)
 
 -- * Non-Determinism Effects
 
@@ -198,6 +210,7 @@
 instance HFunctor Empty where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor Empty
 
 -- | An effect that splits the computation into two branches.
 data Choose :: Effect where
@@ -212,6 +225,7 @@
 instance HFunctor Choose where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor Choose
 
 {- |
 An effect that executes two branches as scopes.
@@ -228,6 +242,7 @@
 instance HFunctor ChooseH where
     hfmap phi (ChooseH a b) = ChooseH (phi a) (phi b)
     {-# INLINE hfmap #-}
+instance PolyHFunctor ChooseH
 
 -- * Fail Effect
 
@@ -241,6 +256,7 @@
 instance HFunctor Fail where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor Fail
 
 -- * Fix Effect
 
@@ -253,6 +269,7 @@
 instance HFunctor Fix where
     hfmap phi (Efix f) = Efix $ phi . f
     {-# INLINE hfmap #-}
+instance PolyHFunctor Fix
 
 -- * Unlift Effect
 
@@ -268,6 +285,8 @@
     hfmap phi (WithRunInBase f) = WithRunInBase \run -> f $ run . phi
     {-# INLINE hfmap #-}
 
+-- The Unlift effect is not polynomial.
+
 -- * CallCC Effect (Sub/Jump-based)
 
 data CC ref :: Effect where
@@ -281,3 +300,4 @@
 instance HFunctor (CC ref) where
     hfmap _ = coerce
     {-# INLINE hfmap #-}
+instance PolyHFunctor (CC ref)
diff --git a/src/Data/Effect/OpenUnion.hs b/src/Data/Effect/OpenUnion.hs
--- a/src/Data/Effect/OpenUnion.hs
+++ b/src/Data/Effect/OpenUnion.hs
@@ -16,7 +16,7 @@
 import Control.Arrow ((&&&))
 import Data.Coerce (coerce)
 import Data.Data (Proxy (Proxy), (:~:) (Refl))
-import Data.Effect (Effect, EffectOrder (FirstOrder, HigherOrder), FirstOrder, LabelOf, OrderCase, OrderOf)
+import Data.Effect (Effect, EffectOrder (FirstOrder, HigherOrder), FirstOrder, LabelOf, OrderCase, OrderOf, PolyHFunctor)
 import Data.Effect.HFunctor (HFunctor, hfmap)
 import Data.Effect.Tag (type (#))
 import Data.Kind (Constraint, Type)
@@ -46,9 +46,17 @@
         HigherOrder -> UnsafeUnion n e HigherOrder (phi . koi)
 {-# INLINE hfmapUnion #-}
 
+-- | The list @es@ consists only of first-order effects.
 class FOEs es
+
 instance FOEs '[]
 instance (FirstOrder e, FOEs es) => FOEs (e ': es)
+
+-- | The list @es@ consists only of polynomial effects.
+class PolyHFunctors es
+
+instance PolyHFunctors '[]
+instance (PolyHFunctor e, PolyHFunctors es) => PolyHFunctors (e ': es)
 
 coerceFOEs :: (FOEs es) => Union es f a -> Union es g a
 coerceFOEs = unsafeCoerce
