diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,10 @@
 Changelog for the `singletons` project
 ======================================
 
+3.0.3 [2024.05.12]
+------------------
+* Allow building with GHC 9.10.
+
 3.0.2 [2022.08.23]
 ------------------
 * Allow building with GHC 9.4.
diff --git a/singletons.cabal b/singletons.cabal
--- a/singletons.cabal
+++ b/singletons.cabal
@@ -1,5 +1,5 @@
 name:           singletons
-version:        3.0.2
+version:        3.0.3
 cabal-version:  1.24
 synopsis:       Basic singleton types and definitions
 homepage:       http://www.github.com/goldfirere/singletons
@@ -15,9 +15,11 @@
               , GHC == 8.8.4
               , GHC == 8.10.7
               , GHC == 9.0.2
-              , GHC == 9.2.4
-              , GHC == 9.4.1
-              , GHCJS==8.4
+              , GHC == 9.2.7
+              , GHC == 9.4.8
+              , GHC == 9.6.5
+              , GHC == 9.8.2
+              , GHC == 9.10.1
 extra-source-files: README.md, CHANGES.md
 license:        BSD3
 license-file:   LICENSE
@@ -58,7 +60,7 @@
 
 library
   hs-source-dirs:     src
-  build-depends:      base >= 4.9 && < 4.18
+  build-depends:      base >= 4.9 && < 4.21
   default-language:   Haskell2010
   exposed-modules:    Data.Singletons
                       Data.Singletons.Decide
@@ -75,5 +77,5 @@
   other-modules:      ByHand
                       ByHand2
 
-  build-depends:      base >= 4.9 && < 4.18,
+  build-depends:      base >= 4.9 && < 4.21,
                       singletons
diff --git a/src/Data/Singletons.hs b/src/Data/Singletons.hs
--- a/src/Data/Singletons.hs
+++ b/src/Data/Singletons.hs
@@ -27,6 +27,10 @@
 {-# LANGUAGE StandaloneKindSignatures #-}
 #endif
 
+#if __GLASGOW_HASKELL__ >= 910
+{-# LANGUAGE TypeAbstractions #-}
+#endif
+
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Singletons
@@ -149,7 +153,11 @@
 #if __GLASGOW_HASKELL__ >= 810
 type Sing :: k -> Type
 #endif
+#if __GLASGOW_HASKELL__ >= 910
+type family Sing @k :: k -> Type
+#else
 type family Sing :: k -> Type
+#endif
 
 {-
 Note [The kind of Sing]
@@ -210,6 +218,20 @@
 -}
 
 -- | A 'SingI' constraint is essentially an implicitly-passed singleton.
+--
+-- In contrast to the 'SingKind' class, which is parameterized over data types
+-- promoted to the kind level, the 'SingI' class is parameterized over values
+-- promoted to the type level. To explain this distinction another way, consider
+-- this code:
+--
+-- @
+-- f = fromSing (sing @(T :: K))
+-- @
+--
+-- Here, @f@ uses methods from both 'SingI' and 'SingKind'. However, the shape
+-- of each constraint is rather different: using 'sing' requires a 'SingI T'
+-- constraint, whereas using 'fromSing' requires a 'SingKind K' constraint.
+--
 -- If you need to satisfy this constraint with an explicit singleton, please
 -- see 'withSingI' or the 'Sing' pattern synonym.
 #if __GLASGOW_HASKELL__ >= 900
@@ -447,6 +469,32 @@
 -- works, see the "Promotion and partial application" section of the
 -- @<https://github.com/goldfirere/singletons/blob/master/README.md README>@.
 --
+-- The singleton for things of kind @a '~>' b@ is 'SLambda'. 'SLambda' values
+-- can be constructed in one of two ways:
+--
+-- 1. With the @singFun*@ family of combinators (e.g., 'singFun1'). For
+--    example, if you have:
+--
+--    @
+--    type Id :: a -> a
+--    sId :: Sing a -> Sing (Id a)
+--    @
+--
+--    Then you can construct a value of type @'Sing' \@(a '~>' a)@ (that is,
+--    @'SLambda' \@a \@a@ like so:
+--
+--    @
+--    sIdFun :: 'Sing' \@(a '~>' a) IdSym0
+--    sIdFun = singFun1 @IdSym0 sId
+--    @
+--
+--    Where @IdSym0 :: a '~>' a@ is the defunctionlized version of @Id@.
+--
+-- 2. Using the 'SingI' class. For example, @'sing' \@IdSym0@ is another way of
+--    defining @sIdFun@ above. The @singletons-th@ library automatically
+--    generates 'SingI' instances for defunctionalization symbols such as
+--    @IdSym0@.
+--
 -- Normal type-level arrows @(->)@ can be converted into defunctionalization
 -- arrows @('~>')@ by the use of the 'TyCon' family of types. (Refer to the
 -- Haddocks for 'TyCon1' to see an example of this in practice.) For this
@@ -512,7 +560,11 @@
 #if __GLASGOW_HASKELL__ >= 810
 type ApplyTyCon :: (k1 -> k2) -> (k1 ~> unmatchable_fun)
 #endif
+#if __GLASGOW_HASKELL__ >= 910
+type family ApplyTyCon @k1 @k2 @unmatchable_fun :: (k1 -> k2) -> (k1 ~> unmatchable_fun) where
+#else
 type family ApplyTyCon :: (k1 -> k2) -> (k1 ~> unmatchable_fun) where
+#endif
 #if __GLASGOW_HASKELL__ >= 808
   ApplyTyCon @k1 @(k2 -> k3) @unmatchable_fun = ApplyTyConAux2
   ApplyTyCon @k1 @k2         @k2              = ApplyTyConAux1
@@ -589,6 +641,29 @@
 -- We can write:
 --
 -- > Map (TyCon1 Succ) [Zero, Succ Zero]
+#if __GLASGOW_HASKELL__ >= 910
+type TyCon1 @k1 @k2 = (TyCon :: (k1 -> k2) -> (k1 ~> k2))
+
+-- | Similar to 'TyCon1', but for two-parameter type constructors.
+type TyCon2 @k1 @k2 @k3 =
+              (TyCon :: (k1 -> k2 -> k3) -> (k1 ~> k2 ~> k3))
+type TyCon3 @k1 @k2 @k3 @k4 =
+              (TyCon :: (k1 -> k2 -> k3 -> k4) -> (k1 ~> k2 ~> k3 ~> k4))
+type TyCon4 @k1 @k2 @k3 @k4 @k5 =
+              (TyCon :: (k1 -> k2 -> k3 -> k4 -> k5) -> (k1 ~> k2 ~> k3 ~> k4 ~> k5))
+type TyCon5 @k1 @k2 @k3 @k4 @k5 @k6 =
+              (TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6)
+                     -> (k1 ~> k2 ~> k3 ~> k4 ~> k5 ~> k6))
+type TyCon6 @k1 @k2 @k3 @k4 @k5 @k6 @k7 =
+              (TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7)
+                     -> (k1 ~> k2 ~> k3 ~> k4 ~> k5 ~> k6 ~> k7))
+type TyCon7 @k1 @k2 @k3 @k4 @k5 @k6 @k7 @k8 =
+              (TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7 -> k8)
+                     -> (k1 ~> k2 ~> k3 ~> k4 ~> k5 ~> k6 ~> k7 ~> k8))
+type TyCon8 @k1 @k2 @k3 @k4 @k5 @k6 @k7 @k8 @k9 =
+              (TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7 -> k8 -> k9)
+                     -> (k1 ~> k2 ~> k3 ~> k4 ~> k5 ~> k6 ~> k7 ~> k8 ~> k9))
+#else
 type TyCon1 = (TyCon :: (k1 -> k2) -> (k1 ~> k2))
 
 -- | Similar to 'TyCon1', but for two-parameter type constructors.
@@ -603,6 +678,7 @@
                      -> (k1 ~> k2 ~> k3 ~> k4 ~> k5 ~> k6 ~> k7 ~> k8))
 type TyCon8 = (TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7 -> k8 -> k9)
                      -> (k1 ~> k2 ~> k3 ~> k4 ~> k5 ~> k6 ~> k7 ~> k8 ~> k9))
+#endif
 #else
 -- | Wrapper for converting the normal type-level arrow into a '~>'.
 -- For example, given:
@@ -644,6 +720,11 @@
 ---- Defunctionalized Sing instance and utilities --------------------
 ----------------------------------------------------------------------
 
+-- | The singleton type for functions. Functions have somewhat special
+-- treatment in @singletons@ (see the Haddocks for @('~>')@ for more information
+-- about this), and as a result, the 'Sing' instance for 'SLambda' is one of the
+-- only such instances defined in the @singletons@ library rather than, say,
+-- @singletons-base@.
 #if __GLASGOW_HASKELL__ >= 810
 type SLambda :: (k1 ~> k2) -> Type
 #endif
diff --git a/tests/ByHand2.hs b/tests/ByHand2.hs
--- a/tests/ByHand2.hs
+++ b/tests/ByHand2.hs
@@ -2,7 +2,7 @@
              DefaultSignatures, ScopedTypeVariables, InstanceSigs,
              MultiParamTypeClasses, FunctionalDependencies,
              UndecidableInstances, CPP #-}
-{-# OPTIONS_GHC -Wno-missing-signatures #-}
+{-# OPTIONS_GHC -Wno-missing-signatures -Wno-orphans #-}
 
 #if __GLASGOW_HASKELL__ < 806
 {-# LANGUAGE TypeInType #-}
