diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,8 @@
+## 0.4.0.0
+
+* Support GHCs 9.6 to 9.14.
+* Fix conflict with 'generic-lens' by using '{-# OVERLAPPING #-}'.
+
 ## 0.3.0.2
 
 * Support GHCs 9.4 to 9.10, fix warnings.
diff --git a/named.cabal b/named.cabal
--- a/named.cabal
+++ b/named.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.4
 name:                named
-version:             0.3.0.2
+version:             0.4.0.0
 synopsis:            Named parameters (keyword arguments) for Haskell
 description:
     `named` is a lightweight library for named function parameters (keyword
@@ -38,7 +38,7 @@
 category:            Control
 build-type:          Simple
 extra-source-files:  ChangeLog.md
-tested-with:         GHC ==9.4.8, GHC ==9.6.6, GHC ==9.10.1
+tested-with:         GHC ==9.6.6, GHC ==9.10.3, GHC ==9.12.4, GHC ==9.14.1
 
 source-repository head
   type: git
@@ -46,7 +46,7 @@
 
 library
   exposed-modules:     Named, Named.Internal
-  build-depends:       base >=4.16 && <4.21
+  build-depends:       base >=4.16 && <4.23
   hs-source-dirs:      src
   default-language:    GHC2021
   ghc-options:         -Wall
@@ -56,8 +56,10 @@
   type:                exitcode-stdio-1.0
   main-is:             Test.hs
   other-modules:       TestImport
-  build-depends:       base >=4.16 && <4.21,
-                       named
+  build-depends:       base >=4.16 && <4.23,
+                       named,
+                       generic-lens,
+                       inspection-testing
   hs-source-dirs:      test
   default-language:    GHC2021
   ghc-options:         -Wall
diff --git a/src/Named.hs b/src/Named.hs
--- a/src/Named.hs
+++ b/src/Named.hs
@@ -9,6 +9,8 @@
 * readability: their names serve as documentation at call site
 * safety: it is impossible to accidentally mix them up
 
+The required extensions are @OverloadedLabels@, @DataKinds@, and @TypeOperators@.
+
 Consider a function to replace a substring with another string:
 
 @
@@ -44,7 +46,7 @@
              '!' \#replacement "\/home\/username\/"
 @
 
-Functions can declare their parameter names in pattern bindings:
+Functions can declare their parameter names in pattern bindings (via the extension @ViewPatterns@):
 
 @
 replace ('arg' \#needle -> n) ('arg' \#replacement -> r) ('arg' \#haystack -> h) =
@@ -151,6 +153,35 @@
       '!' #handle logfile
 @
 
+= An issue with polymorphic return types
+
+A limitation of 'defaults' is that it is not possible to pass it to a function with a polymorphic return type. In particular: to mtl-style functions. The following code produces a compilation error:
+
+@
+foo :: "x" ':?' Int -> m Int
+
+bar :: m Int
+bar = foo '!' 'defaults'
+@
+
+A workaround is to return a newtype wrapper around @m@:
+
+@
+newtype M m a = M { runM :: m a }
+  deriving (Functor, Applicative, Monad)
+
+foo :: "x" ':?' Int -> M m Int
+
+bar :: M m Int
+bar = foo '!' 'defaults'
+
+bar' :: m Int
+bar' = runM (foo '!' 'defaults')
+@
+
+Note: the type signature of 'bar' is required.
+
+See [issue #15](https://github.com/monadfix/named/issues/15) "Problem with type inference caused by @! defaults@" for details.
 -}
 module Named
   (
diff --git a/src/Named/Internal.hs b/src/Named/Internal.hs
--- a/src/Named/Internal.hs
+++ b/src/Named/Internal.hs
@@ -51,7 +51,9 @@
 
 newtype Param p = Param p
 
-instance (p ~ NamedF f a name, InjValue f) => IsLabel name (a -> Param p) where
+-- It needs to be OVERLAPPING to avoid conflicts with 'generic-lens'.
+-- See the discussion for more context: https://github.com/monadfix/named/issues/8
+instance {-# OVERLAPPING #-} (p ~ NamedF f a name, InjValue f) => IsLabel name (a -> Param p) where
   fromLabel a = Param (fromLabel @name a)
   {-# INLINE fromLabel #-}
 
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,22 +1,31 @@
 {-# LANGUAGE OverloadedLabels, DataKinds, TypeOperators, ViewPatterns,
-             PartialTypeSignatures #-}
+             PartialTypeSignatures, TemplateHaskell #-}
 
 {-# OPTIONS -fno-warn-partial-type-signatures #-}
 
 module Main where
 
 import Data.Maybe (fromMaybe)
+import Data.Functor (void)
 import Data.Function ((&))
+import Data.Generics.Labels () -- to ensure our instances won't conflict with IsLabel from generic-lens
 import Named
+import Test.Inspection
 
 test1 ::
   String ->
   "a" :! Bool ->
   "b" :! Bool ->
-  IO ()
-test1 "str" (arg #a -> True) (arg #b -> False) = return ()
-test1 _ _ _ = error "unexpected flags or str"
+  IO Bool
+test1 "str" (arg #a -> True) (arg #b -> False) = return True
+test1 _ _ _ = return False
 
+test1_raw :: String -> Bool -> Bool -> IO Bool
+test1_raw "str" True False = return True
+test1_raw _ _ _ = return False
+
+inspect $ 'test1 ==- 'test1_raw
+
 test1_1 =
   test1 "str"
     ! #a True
@@ -48,11 +57,20 @@
 test2 :: "x" :! Int -> Int
 test2 x = arg #x x * 2
 
+test2_raw :: Int -> Int
+test2_raw x = x * 2
+
+inspect $ 'test2 ==- 'test2_raw
+
 test2_1 :: Int
 test2_1 = test2 ! #x 5 + test2 ! #x 3
 
 test3 (arg #a -> a) (arg #b -> b) = a + b
 
+test3_raw a b = a + b
+
+inspect $ 'test3 ==- 'test3_raw
+
 -- must not typecheck:
 --     Couldn't match type ‘"a"’ with ‘"b"’
 --     arising from the overloaded label ‘#b’
@@ -71,6 +89,11 @@
   (ArgF y)
   = if b then x else (fromMaybe 'y' y)
 
+test4_raw :: Bool -> Maybe Char -> Maybe Char -> Char
+test4_raw b (fromMaybe 'x' -> x) y = if b then x else fromMaybe 'y' y
+
+inspect $ 'test4 ==- 'test4_raw
+
 test4_1 = test4 ! #b True ! defaults
 test4_2 = test4 ! #b False ! defaults
 test4_3 = test4 ! #x 'z' ! #b True ! defaults
@@ -81,21 +104,59 @@
 test5_1 :: ("bar" :! Int -> ()) -> ()
 test5_1 f = f ! #bar 3
 
+test5_1_raw :: (Int -> ()) -> ()
+test5_1_raw f = f 3
+
+inspect $ 'test5_1 ==- 'test5_1_raw
+
 test5_2 :: ("bar" :! Int -> ()) -> "bar" :! Int -> ()
 test5_2 f x = f x
 
+test5_2_raw :: (Int -> ()) -> Int -> ()
+test5_2_raw f x = f x
+
+inspect $ 'test5_2 ==- 'test5_2_raw
+
 test6 :: Maybe ("x" :! Int -> Int) -> Int
 test6 Nothing = 0
 test6 (Just f) = f ! #x 42
 
+test6_raw :: Maybe (Int -> Int) -> Int
+test6_raw Nothing = 0
+test6_raw (Just f) = f 42
+
+inspect $ 'test6 ==- 'test6_raw
+
+newtype M m a = M { runM :: m a }
+  deriving (Functor, Applicative, Monad)
+
+-- must typecheck:
+
+test7_1 :: "x" :? Int -> M m Int
+test7_1 = undefined
+
+test7_2 :: M m Int
+test7_2 = test7_1 ! defaults
+
+test7_3 :: m Int
+test7_3 = runM (test7_1 ! defaults)
+
+-- doesn't typecheck (yet):
+--
+-- test7_4 :: "x" :? Int -> m Int
+-- test7_4 = undefined
+
+-- test7_5 :: m Int
+-- test7_5 = test7_1 ! defaults
+
 main :: IO ()
 main = do
-  test1_1
-  test1_2
-  test1_3
-  test1_4
-  test1_5
-  test1_6
+  void test1_1
+  void test1_2
+  void test1_3
+  void test1_4
+  void test1_5
+  void test1_6
   test2_1 `mustBe` 16
   test4_1 `mustBe` 'x'
   test4_2 `mustBe` 'y'
