diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Revision history for haskell-candid
 
+## 0.4.0.2 -- 2023-06-03
+
+* Bump dependencies
+* GHC-9.t
+
 ## 0.4.0.1 -- 2023-01-01
 
 * Bump dependencies
diff --git a/candid.cabal b/candid.cabal
--- a/candid.cabal
+++ b/candid.cabal
@@ -1,6 +1,6 @@
-cabal-version:      >=1.10
+cabal-version:      2.0
 name:               candid
-version:            0.4.0.1
+version:            0.4.0.2
 license:            Apache
 license-file:       LICENSE
 maintainer:         mail@joachim-breitner.de
@@ -47,42 +47,42 @@
     default-language: Haskell2010
     ghc-options:      -Wall -Wno-name-shadowing
     build-depends:
-        base >=4.12 && <5,
-        text >=1.2.3.1 && <2.1,
-        dlist >=0.8.0.8 && <1.1,
-        vector >=0.12.1.2 && <0.14,
-        bytestring >=0.10.8.2 && <0.12,
-        mtl >=2.2.2 && <2.4,
-        transformers >=0.5.6.2 && <0.7,
-        hex-text >=0.1.0.0 && <0.2,
-        crc >=0.1.0.0 && <0.2,
-        megaparsec >=8 && <9.4,
-        parser-combinators >=1.2 && <1.4,
-        scientific >=0.3.6.2 && <0.4,
-        cereal >=0.5.8.1 && <0.6,
-        leb128-cereal ==1.2.*,
-        containers >=0.6.0.1 && <0.7,
-        unordered-containers >=0.2.10.0 && <0.3,
-        row-types > 1.0.0.0 && < 1.1,
-        constraints >=0.12 && <0.14,
-        prettyprinter >=1.7 && <1.8,
-        template-haskell,
-        base32 >=0.1.1.2 && <0.3,
-        split >=0.2.3.4 && <0.3,
-        file-embed
+        base ^>=4.14.3.0 || ^>=4.15.1.0 || ^>=4.16.3.0 || ^>=4.17.0.0 || ^>=4.18.0.0,
+        text ^>=1.2.4.1 || ^>=2.0.1,
+        dlist ^>=1.0,
+        vector ^>=0.12.3.1 || ^>=0.13.0.0,
+        bytestring ^>=0.10.12.0 || ^>=0.11.3.1,
+        mtl ^>=2.2.2 || ^>=2.3.1,
+        transformers ^>=0.5.6.2 || ^>=0.6.1.0,
+        hex-text ^>=0.1.0.7,
+        crc ^>=0.1.1.1,
+        megaparsec ^>=9.2.1 || ^>=9.3.1,
+        parser-combinators ^>=1.3.0,
+        scientific ^>=0.3.7.0,
+        cereal ^>=0.5.8.3,
+        leb128-cereal ^>=1.2,
+        containers ^>=0.6.4.1,
+        unordered-containers ^>=0.2.19.1,
+        row-types ^>=1.0.1.2,
+        constraints ^>=0.13.4,
+        prettyprinter ^>=1.7.1,
+        template-haskell ^>=2.16.0.0 || ^>=2.17.0.0 || ^>=2.18.0.0 || ^>=2.19.0.0 || ^>=2.20.0.0,
+        base32 ^>=0.2.2.0 || ^>=0.3.1.0,
+        split ^>=0.2.3.5,
+        file-embed ^>=0.0.15.0
 
 executable hcandid
     main-is:          hcandid.hs
     default-language: Haskell2010
     ghc-options:      -Wall -Wno-name-shadowing
     build-depends:
-        base ==4.*,
-        candid -any,
-        optparse-applicative >=0.15.1.0 && <0.18,
-        text >=1.2.3.1 && <2.1,
-        bytestring >=0.10.8.2 && <0.12,
-        hex-text >=0.1.0.0 && <0.2,
-        prettyprinter >=1.6.2 && <1.8
+        base ^>=4.14.3.0 || ^>=4.15.1.0 || ^>=4.16.3.0 || ^>=4.17.0.0 || ^>=4.18.0.0,
+        candid,
+        optparse-applicative ^>=0.17.0.0 || ^>=0.18.1.0,
+        text ^>=1.2.4.1 || ^>=2.0.1,
+        bytestring ^>=0.10.12.0 || ^>=0.11.3.1,
+        hex-text ^>=0.1.0.7,
+        prettyprinter ^>=1.7.1
 
 test-suite test
     type:             exitcode-stdio-1.0
@@ -96,23 +96,23 @@
     default-language: Haskell2010
     ghc-options:      -Wall -Wno-name-shadowing -rtsopts
     build-depends:
-        base ==4.*,
-        tasty >=0.7 && <1.5,
-        tasty-hunit >=0.10.0.2 && <0.11,
-        tasty-smallcheck >=0.8.1 && <0.9,
-        tasty-quickcheck >=0.10 && <0.11,
-        tasty-rerun >=1.1.17 && <1.2,
-        smallcheck >=1.2 && <1.3,
-        candid -any,
-        bytestring >=0.10.8.2 && <0.12,
-        text >=1.2.3.1 && <2.1,
-        vector >=0.12.1.2 && <0.14,
-        prettyprinter >=1.6.2 && <1.8,
-        unordered-containers >=0.2.10.0 && <0.3,
-        row-types > 1.0.0.0 && < 1.1,
-        directory >=1.3.3.0 && <1.4,
-        filepath >=1.4.2.1 && <1.5,
-        template-haskell
+        base ^>=4.14.3.0 || ^>=4.15.1.0 || ^>=4.16.3.0 || ^>=4.17.0.0 || ^>=4.18.0.0,
+        tasty ^>=1.4.3,
+        tasty-hunit ^>=0.10.0.3,
+        tasty-smallcheck ^>=0.8.2,
+        tasty-quickcheck ^>=0.10.2,
+        tasty-rerun ^>=1.1.18,
+        smallcheck ^>=1.2.1,
+        candid,
+        bytestring ^>=0.10.12.0 || ^>=0.11.3.1,
+        text ^>=1.2.4.1 || ^>=2.0.1,
+        vector ^>=0.12.3.1 || ^>=0.13.0.0,
+        prettyprinter ^>=1.7.1,
+        unordered-containers ^>=0.2.19.1,
+        row-types ^>=1.0.1.2,
+        directory ^>=1.3.6.0,
+        filepath ^>=1.4.2.1,
+        template-haskell ^>=2.16.0.0 || ^>=2.17.0.0 || ^>=2.18.0.0 || ^>=2.19.0.0 || ^>=2.20.0.0
 
 test-suite doctest
     type:             exitcode-stdio-1.0
@@ -120,9 +120,13 @@
     default-language: Haskell2010
     ghc-options:      -threaded
     build-depends:
-        base ==4.*,
-        candid -any,
-        doctest,
-        row-types > 1.0.0.0 && < 1.1,
-        leb128-cereal ==1.2.*,
-        prettyprinter >=1.6.2 && <1.8
+        base ^>=4.14.3.0 || ^>=4.15.1.0 || ^>=4.16.3.0 || ^>=4.17.0.0 || ^>=4.18.0.0,
+        candid,
+        doctest ^>=0.20.1 || ^>=0.21.1,
+        row-types ^>=1.0.1.2,
+        leb128-cereal ^>=1.2,
+        prettyprinter ^>=1.7.1
+
+source-repository head
+  type:     git
+  location: https://github.com/nomeata/haskell-cabal
diff --git a/src/Codec/Candid.hs b/src/Codec/Candid.hs
--- a/src/Codec/Candid.hs
+++ b/src/Codec/Candid.hs
@@ -282,10 +282,17 @@
 
 For convenience, we name its type
 
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
 >>> :t service
+service :: Rec (R ["get" :-> (() -> IO Integer), "inc" :-> (Integer -> IO ())])
+>>> :set -XTypeOperators -XDataKinds -XFlexibleContexts
+>>> type Interface = R ["get" :-> (() -> IO Integer), "inc" :-> (Integer -> IO ())]
+#else
+>>> :t service
 service :: Rec ('R '[ "get" ':-> (() -> IO Integer), "inc" ':-> (Integer -> IO ())])
 >>> :set -XTypeOperators -XDataKinds -XFlexibleContexts
 >>> type Interface = 'R '[ "get" ':-> (() -> IO Integer), "inc" ':-> (Integer -> IO ())]
+#endif
 
 Now we can turn this into a raw service operating on bytes:
 
diff --git a/src/Codec/Candid/Coerce.hs b/src/Codec/Candid/Coerce.hs
--- a/src/Codec/Candid/Coerce.hs
+++ b/src/Codec/Candid/Coerce.hs
@@ -13,9 +13,9 @@
 import qualified Data.Vector as V
 import qualified Data.ByteString.Lazy as BS
 import qualified Data.Map as M
+import Control.Monad
 import Control.Monad.State.Lazy
 import Control.Monad.Except
-import Control.Monad
 
 import Codec.Candid.FieldName
 import Codec.Candid.Types
diff --git a/src/Codec/Candid/Encode.hs b/src/Codec/Candid/Encode.hs
--- a/src/Codec/Candid/Encode.hs
+++ b/src/Codec/Candid/Encode.hs
@@ -14,14 +14,14 @@
 import qualified Data.ByteString.Builder as B
 import qualified Data.Map as M
 import Data.Scientific
+import Control.Monad
 import Control.Monad.State.Lazy
+import Control.Monad.RWS.Lazy
 import Data.Bifunctor
 import Data.List
 import Data.Void
-import Control.Monad.RWS.Lazy
 import Data.Serialize.LEB128
 import Prettyprinter
-import Control.Monad
 
 import Codec.Candid.Data
 import Codec.Candid.TypTable
diff --git a/src/Codec/Candid/Generic.hs b/src/Codec/Candid/Generic.hs
--- a/src/Codec/Candid/Generic.hs
+++ b/src/Codec/Candid/Generic.hs
@@ -14,6 +14,7 @@
 import qualified Data.Row as R
 import qualified Data.Row.Records as R
 import qualified Data.Row.Variants as V
+import qualified Data.Row.Dictionaries as R
 import Data.Typeable
 
 import Codec.Candid.Class
@@ -27,6 +28,12 @@
     , Candid (R.Rec (R.NativeRow a))
     , R.ToNative a
     , R.FromNative a
+    -- Superclass constraints that need to be explicit since GHC 9.6
+    , Typeable (R.NativeRow a)
+    , V.AllUniqueLabels (R.NativeRow a)
+    , V.AllUniqueLabels (V.Map (Either String) (R.NativeRow a))
+    , V.Forall (R.NativeRow a) R.Unconstrained1
+    , V.Forall (R.NativeRow a) Candid
     )
 instance CanBeCandidRecord a => Candid (AsRecord a) where
     type AsCandid (AsRecord a) = AsCandid (R.Rec (R.NativeRow a))
@@ -41,8 +48,13 @@
     , Candid (V.Var (V.NativeRow a))
     , V.ToNative a
     , V.FromNative a
+    -- Superclass constraints that need to be explicit since GHC 9.6
+    , Typeable (V.NativeRow a)
+    , V.AllUniqueLabels (V.NativeRow a)
+    , V.AllUniqueLabels (V.Map (Either String) (V.NativeRow a))
+    , V.Forall (V.NativeRow a) R.Unconstrained1
+    , V.Forall (V.NativeRow a) Candid
     )
-
 instance CanBeCandidVariant a => Candid (AsVariant a) where
     type AsCandid (AsVariant a) = AsCandid (V.Var (V.NativeRow a))
     toCandid = toCandid @(V.Var (V.NativeRow a)) . V.fromNative . unAsVariant
diff --git a/src/Codec/Candid/Subtype.hs b/src/Codec/Candid/Subtype.hs
--- a/src/Codec/Candid/Subtype.hs
+++ b/src/Codec/Candid/Subtype.hs
@@ -14,10 +14,10 @@
 import qualified Data.Map as M
 import Data.Bifunctor
 import Data.Tuple
+import Control.Monad
 import Control.Monad.State.Lazy
 import Control.Monad.Except
 import Control.Monad.Trans.Except
-import Control.Monad
 
 import Codec.Candid.Types
 import Codec.Candid.TypTable
diff --git a/src/Codec/Candid/TypTable.hs b/src/Codec/Candid/TypTable.hs
--- a/src/Codec/Candid/TypTable.hs
+++ b/src/Codec/Candid/TypTable.hs
@@ -14,13 +14,13 @@
 module Codec.Candid.TypTable where
 
 import qualified Data.Map as M
+import Control.Monad
 import Control.Monad.State.Lazy
 import Data.Void
 import Prettyprinter
 import Data.DList (singleton, DList)
 import Data.Graph
 import Data.Foldable
-import Control.Monad
 
 import Codec.Candid.Types
 
