diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,6 @@
+## generic-lens-2.2.2.0 (2023-04-15)
+- Support unprefixed constructor prisms on GHC 9.6 (#152)
+
 ## generic-lens-2.2.1.0 (2022-01-22)
 - GHC 9.2 compatibility
 
diff --git a/generic-lens.cabal b/generic-lens.cabal
--- a/generic-lens.cabal
+++ b/generic-lens.cabal
@@ -1,5 +1,5 @@
 name:                 generic-lens
-version:              2.2.1.0
+version:              2.2.2.0
 synopsis:             Generically derive traversals, lenses and prisms.
 description:          This library uses GHC.Generics to derive efficient optics (traversals, lenses and prisms) for algebraic data types in a type-directed way, with a focus on good type inference and error messages when possible.
                       .
@@ -47,7 +47,7 @@
   build-depends:      base        >= 4.11 && < 5
                     , generic-lens-core == 2.2.1.0
                     , profunctors
-                    , text        >= 1.2 && < 1.3
+                    , text        >= 1.2 && < 1.3 || >= 2.0 && < 2.1
 
   hs-source-dirs:     src
   default-language:   Haskell2010
@@ -101,5 +101,7 @@
   type:               exitcode-stdio-1.0
   ghc-options:        -threaded
   main-is:            doctest.hs
-  build-depends:      base >4 && <5, doctest
+  build-depends:      base >4 && <5
+                    , doctest
+                    , lens
   hs-source-dirs:     examples
diff --git a/src/Data/Generics/Labels.hs b/src/Data/Generics/Labels.hs
--- a/src/Data/Generics/Labels.hs
+++ b/src/Data/Generics/Labels.hs
@@ -42,7 +42,7 @@
 import "this" Data.Generics.Internal.VL.Prism (Prism)
 
 import Data.Profunctor    (Choice)
-import Data.Type.Bool     (type (&&))
+import Data.Type.Bool     (type (&&), If)
 import Data.Type.Equality (type (==))
 
 import GHC.OverloadedLabels
@@ -50,10 +50,10 @@
 
 -- $sec1
 -- An instance for creating lenses and prisms with @#identifiers@ from the
--- @OverloadedLabels@ extension.  Note that since overloaded labels do not
+-- @OverloadedLabels@ extension.  Note that since overloaded labels did not
 -- support symbols starting with capital letters, all prisms (which come from
 -- constructor names, which are capitalized) must be prefixed with an underscore
--- (e.g. @#_ConstructorName@).
+-- (e.g. @#_ConstructorName@) when you use a GHC older than 9.6.
 --
 -- Morally:
 --
@@ -107,28 +107,40 @@
 instance {-# INCOHERENT #-} AsConstructor' name s a => Constructor name s s a a where
   constructorPrism = _Ctor' @name
 
-type family BeginsWithCapital (name :: Symbol) :: Bool where
-  BeginsWithCapital name = CmpSymbol "_@" name == 'LT && CmpSymbol "_[" name == 'GT
+data LabelType = FieldType | LegacyConstrType | ConstrType
 
-instance ( capital ~ BeginsWithCapital name
-         , IsLabelHelper capital name p f s t a b
+type family ClassifyLabel (name :: Symbol) :: LabelType where
+  ClassifyLabel name =
+    If (CmpSymbol "_@" name == 'LT && CmpSymbol "_[" name == 'GT)
+      'LegacyConstrType
+      ( If (CmpSymbol "@" name == 'LT && CmpSymbol "[" name == 'GT)
+          'ConstrType
+          'FieldType
+      )
+
+instance ( labelType ~ ClassifyLabel name
+         , IsLabelHelper labelType name p f s t a b
          , pafb ~ p a (f b), psft ~ p s (f t)) => IsLabel name (pafb -> psft) where
-  fromLabel = labelOutput @capital @name @p @f
+  fromLabel = labelOutput @labelType @name @p @f
 
 -- | This helper class allows us to customize the output type of the lens to be
 -- either 'Prism' or 'Lens' (by choosing appropriate @p@ and @f@) as well as to
 -- choose between whether we're dealing with a lens or a prism.  The choice is
--- made by whether the @capital@ argument is true or false, which is determined by
--- whether the symbol starts with an underscore followed by a capital letter
--- (a check done in the 'IsLabel' instance above).  If so, then we're dealing
--- with a constructor name, which should be a prism, and otherwise, it's a field
--- name, so we have a lens.
-class IsLabelHelper capital name p f s t a b where
+-- made by the @labelType@ argument, which is determined by whether the symbol
+-- starts with a capital letter, optionally preceded by an underscore (a check
+-- done in the 'IsLabel' instance above).  If so, then we're dealing with a
+-- constructor name, which should be a prism, and otherwise, it's a field name,
+-- so we have a lens.
+class IsLabelHelper labelType name p f s t a b where
   labelOutput :: p a (f b) -> p s (f t)
 
-instance (Functor f, Field name s t a b) => IsLabelHelper 'False name (->) f s t a b where
+instance (Functor f, Field name s t a b) => IsLabelHelper 'FieldType name (->) f s t a b where
   labelOutput = fieldLens @name
 
 instance ( Applicative f, Choice p, Constructor name s t a b
-         , name' ~ AppendSymbol "_" name) => IsLabelHelper 'True name' p f s t a b where
+         , name' ~ AppendSymbol "_" name) => IsLabelHelper 'LegacyConstrType name' p f s t a b where
+  labelOutput = constructorPrism @name
+
+instance ( Applicative f, Choice p, Constructor name s t a b
+         ) => IsLabelHelper 'ConstrType name p f s t a b where
   labelOutput = constructorPrism @name
diff --git a/src/Data/Generics/Product/Fields.hs b/src/Data/Generics/Product/Fields.hs
--- a/src/Data/Generics/Product/Fields.hs
+++ b/src/Data/Generics/Product/Fields.hs
@@ -155,7 +155,8 @@
 -- instance {-# OVERLAPPING #-} HasField' field s a => HasField field s s a a where
 --   field f s = field' @field f s
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d field
 -- field
 --   :: (HasField field s t a b, Functor f) => (a -> f b) -> s -> f t
diff --git a/src/Data/Generics/Product/Positions.hs b/src/Data/Generics/Product/Positions.hs
--- a/src/Data/Generics/Product/Positions.hs
+++ b/src/Data/Generics/Product/Positions.hs
@@ -128,7 +128,8 @@
   position = position0 @i
   {-# INLINE position #-}
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d position
 -- position
 --   :: (HasPosition i s t a b, Functor f) => (a -> f b) -> s -> f t
diff --git a/src/Data/Generics/Product/Subtype.hs b/src/Data/Generics/Product/Subtype.hs
--- a/src/Data/Generics/Product/Subtype.hs
+++ b/src/Data/Generics/Product/Subtype.hs
@@ -117,14 +117,16 @@
 instance {-# OVERLAPPING #-} Subtype a a where
   super = id
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d super
 -- super
 --   :: (Subtype sup sub, Functor f) => (sup -> f sup) -> sub -> f sub
 instance {-# OVERLAPPING #-} Subtype a Void where
   super = undefined
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d super @Int
 -- super @Int
 --   :: (Subtype Int sub, Functor f) => (Int -> f Int) -> sub -> f sub
diff --git a/src/Data/Generics/Product/Typed.hs b/src/Data/Generics/Product/Typed.hs
--- a/src/Data/Generics/Product/Typed.hs
+++ b/src/Data/Generics/Product/Typed.hs
@@ -109,10 +109,11 @@
     setTyped a _ = a
     {-# INLINE setTyped #-}
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d typed
 -- typed :: (HasType a s, Functor f) => (a -> f a) -> s -> f s
 --
--- Note that this might not longer be needed given the above 'HasType a a' instance.
+-- Note that this might not longer be needed given the 'HasType a a' instance.
 instance {-# OVERLAPPING #-} HasType a Void where
   typed = undefined
diff --git a/src/Data/Generics/Sum/Constructors.hs b/src/Data/Generics/Sum/Constructors.hs
--- a/src/Data/Generics/Sum/Constructors.hs
+++ b/src/Data/Generics/Sum/Constructors.hs
@@ -129,7 +129,8 @@
   _Ctor eta = _Ctor0 @ctor eta
   {-# INLINE _Ctor #-}
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d _Ctor
 -- _Ctor
 --   :: (AsConstructor ctor s t a b, Choice p, Applicative f) =>
diff --git a/src/Data/Generics/Sum/Subtype.hs b/src/Data/Generics/Sum/Subtype.hs
--- a/src/Data/Generics/Sum/Subtype.hs
+++ b/src/Data/Generics/Sum/Subtype.hs
@@ -109,22 +109,25 @@
   {-# INLINE _Sub #-}
 
 -- | Reflexive case
+--
 --  >>> _Sub # dog :: Animal
 --  Dog (MkDog {name = "Shep", age = 3})
 instance {-# OVERLAPPING #-} AsSubtype a a where
   _Sub = id
   {-# INLINE _Sub #-}
 
--- | See Note [Uncluttering type signatures]
---_Sub
---  :: (AsSubtype sub sup, Data.Profunctor.Choice.Choice p,
---      Applicative f) =>
---     p sub (f sub) -> p sup (f sup)
+-- | Uncluttering type signatures (see 'Void')
+--
+-- >>> :t +d _Sub
+-- _Sub
+--   :: (AsSubtype sub sup, Choice p, Applicative f) =>
+--      p sub (f sub) -> p sup (f sup)
 instance {-# OVERLAPPING #-} AsSubtype a Void where
   injectSub = undefined
   projectSub = undefined
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d _Sub @Int
 -- _Sub @Int
 --   :: (AsSubtype Int sup, Choice p, Applicative f) =>
diff --git a/src/Data/Generics/Sum/Typed.hs b/src/Data/Generics/Sum/Typed.hs
--- a/src/Data/Generics/Sum/Typed.hs
+++ b/src/Data/Generics/Sum/Typed.hs
@@ -101,7 +101,8 @@
   _Typed eta = prism2prismvl Core.derived eta
   {-# INLINE _Typed #-}
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d _Typed
 -- _Typed
 --   :: (AsType a s, Choice p, Applicative f) => p a (f a) -> p s (f s)
@@ -110,7 +111,8 @@
   injectTyped = undefined
   projectTyped = undefined
 
--- | See Note [Uncluttering type signatures]
+-- | Uncluttering type signatures (see 'Void')
+--
 -- >>> :t +d _Typed @Int
 -- _Typed @Int
 --   :: (AsType Int s, Choice p, Applicative f) =>
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -4,6 +4,7 @@
 {-# OPTIONS_GHC -funfolding-use-threshold=150 #-}
 
 {-# LANGUAGE AllowAmbiguousTypes             #-}
+{-# LANGUAGE CPP                             #-}
 {-# LANGUAGE DataKinds                       #-}
 {-# LANGUAGE DeriveGeneric                   #-}
 {-# LANGUAGE DuplicateRecordFields           #-}
@@ -266,6 +267,11 @@
   , (valLabel ^? #_RecB . _1  ) ~=? Just 3
   , (valLabel ^? #_RecB       ) ~=? Just (3, True)
   , (valLabel ^? #_RecC       ) ~=? Nothing
+#if MIN_VERSION_base(4,18,0)
+  , (valLabel ^? #RecB . _1  ) ~=? Just 3
+  , (valLabel ^? #RecB       ) ~=? Just (3, True)
+  , (valLabel ^? #RecC       ) ~=? Nothing
+#endif
   , customTypesTest
   ]
   where valLabel = RecB 3 True 
