diff --git a/ascii-case.cabal b/ascii-case.cabal
--- a/ascii-case.cabal
+++ b/ascii-case.cabal
@@ -1,7 +1,7 @@
 cabal-version: 3.0
 
 name: ascii-case
-version: 1.0.1.2
+version: 1.0.1.3
 synopsis: ASCII letter case
 category: Data, Text
 
@@ -25,29 +25,26 @@
     location: git://github.com/typeclasses/ascii-case.git
 
 common base
-    default-language: Haskell2010
+    default-language: GHC2021
     ghc-options: -Wall
 
     default-extensions:
+        BlockArguments
+        DeriveAnyClass
+        DerivingStrategies
+        LambdaCase
         NoImplicitPrelude
 
     build-depends:
-        ascii-char ^>= 1.0
-      , base ^>= 4.14 || ^>= 4.15 || ^>= 4.16 || ^>= 4.17
+      , ascii-char ^>= 1.0
+      , base ^>= 4.16 || ^>= 4.17 || ^>= 4.18
 
 library
     import: base
     hs-source-dirs: library
 
-    default-extensions:
-        StandaloneDeriving
-        DerivingStrategies
-        DeriveAnyClass
-        DeriveDataTypeable
-        DeriveGeneric
-
     build-depends:
-        hashable ^>= 1.3.5 || ^>= 1.4
+      , hashable ^>= 1.3.5 || ^>= 1.4
 
     exposed-modules:
         ASCII.Case
@@ -59,5 +56,5 @@
     main-is: Main.hs
 
     build-depends:
-        ascii-case
-      , hspec ^>= 2.8.5 || ^>= 2.9 || ^>= 2.10
+      , ascii-case
+      , hspec ^>= 2.8.5 || ^>= 2.9 || ^>= 2.10 || ^>= 2.11
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,7 @@
+### 1.0.1.3 (2023-06-21)
+
+Dropped support for GHC 9.0 (base 4.15)
+
 ### 1.0.1.2 (2023-01-01)
 
 Minor Cabal correction (change `extra-doc-files` to `extra-source-files`)
diff --git a/library/ASCII/Case.hs b/library/ASCII/Case.hs
--- a/library/ASCII/Case.hs
+++ b/library/ASCII/Case.hs
@@ -1,14 +1,13 @@
-{- |
-
-/Case/ is a property of letters. /A-Z/ are /upper case/ letters, and
-/a-z/ are /lower case/ letters. No other ASCII characters have case.
-
--}
-
-module ASCII.Case ( Case (..), letterCase, isCase, toCase, opposite ) where
+-- |
+--
+-- /Case/ is a property of letters. /A-Z/ are /upper case/ letters, and
+-- /a-z/ are /lower case/ letters. No other ASCII characters have case.
+module ASCII.Case (Case (..), letterCase, isCase, toCase, opposite) where
 
 import ASCII.Char (Char (..))
+import ASCII.Char qualified as Char
 import Data.Bool (Bool, otherwise)
+import Data.Bool qualified as Bool
 import Data.Data (Data)
 import Data.Eq (Eq)
 import Data.Function ((.))
@@ -16,15 +15,14 @@
 import Data.Maybe (Maybe (..))
 import Data.Ord (Ord, (<=), (>=))
 import GHC.Generics (Generic)
-import Prelude (Bounded, Enum, Int, (+), (-))
 import Text.Show (Show)
-
-import qualified ASCII.Char as Char
-import qualified Data.Bool as Bool
+import Prelude (Bounded, Enum, Int, (+), (-))
 
-data Case =
-    UpperCase -- ^ The letters from 'CapitalLetterA' to 'CapitalLetterZ'.
-  | LowerCase -- ^ The letters from 'SmallLetterA' to 'SmallLetterZ'.
+data Case
+  = -- | The letters from 'CapitalLetterA' to 'CapitalLetterZ'.
+    UpperCase
+  | -- | The letters from 'SmallLetterA' to 'SmallLetterZ'.
+    LowerCase
 
 deriving stock instance Eq Case
 
@@ -42,67 +40,61 @@
 
 deriving anyclass instance Hashable Case
 
-{- | Determines whether a character is a letter, and if so, whether it is upper or lower case.
-
->>> map letterCase [CapitalLetterR, SmallLetterR, DollarSign]
-[Just UpperCase,Just LowerCase,Nothing]
-
--}
-
+-- | Determines whether a character is a letter, and if so, whether it is upper or lower case.
+--
+-- >>> map letterCase [CapitalLetterR, SmallLetterR, DollarSign]
+-- [Just UpperCase,Just LowerCase,Nothing]
 letterCase :: Char -> Maybe Case
-letterCase x | isCase UpperCase x = Just UpperCase
-             | isCase LowerCase x = Just LowerCase
-             | otherwise          = Nothing
-
-{- | Determines whether a character is a letter of a particular case.
-
->>> map (isCase UpperCase) [CapitalLetterR,SmallLetterR,DollarSign]
-[True,False,False]
-
--}
+letterCase x
+  | isCase UpperCase x = Just UpperCase
+  | isCase LowerCase x = Just LowerCase
+  | otherwise = Nothing
 
+-- | Determines whether a character is a letter of a particular case.
+--
+-- >>> map (isCase UpperCase) [CapitalLetterR,SmallLetterR,DollarSign]
+-- [True,False,False]
 isCase :: Case -> Char -> Bool
-isCase c x = (Bool.&&) ( x >= a ) ( x <= z ) where (a, z) = az c
+isCase c x = (Bool.&&) (x >= a) (x <= z) where (a, z) = az c
 
 az :: Case -> (Char, Char)
-az UpperCase = (CapitalLetterA, CapitalLetterZ)
-az LowerCase = (SmallLetterA, SmallLetterZ)
-
-{- | Maps a letter character to its upper/lower case equivalent.
-
->>> toCase UpperCase SmallLetterX
-CapitalLetterX
-
->>> toCase LowerCase CapitalLetterF
-SmallLetterF
-
-Characters that are already in the requested case are unmodified by this transformation.
-
->>> toCase UpperCase CapitalLetterA
-CapitalLetterA
-
-Characters that are not letters, such as exclamation mark, are unmodified by this transformation.
-
->>> toCase UpperCase ExclamationMark
-ExclamationMark
-
--}
+az = \case
+  UpperCase -> (CapitalLetterA, CapitalLetterZ)
+  LowerCase -> (SmallLetterA, SmallLetterZ)
 
+-- | Maps a letter character to its upper/lower case equivalent.
+--
+-- >>> toCase UpperCase SmallLetterX
+-- CapitalLetterX
+--
+-- >>> toCase LowerCase CapitalLetterF
+-- SmallLetterF
+--
+-- Characters that are already in the requested case are unmodified by this transformation.
+--
+-- >>> toCase UpperCase CapitalLetterA
+-- CapitalLetterA
+--
+-- Characters that are not letters, such as exclamation mark, are unmodified by this transformation.
+--
+-- >>> toCase UpperCase ExclamationMark
+-- ExclamationMark
 toCase :: Case -> Char -> Char
 toCase c x = if isCase (opposite c) x then changeCaseUnsafe c x else x
 
 -- | Change a letter to the given case, assuming that the input character is a letter of the opposite case.
-
 changeCaseUnsafe :: Case -> Char -> Char
 changeCaseUnsafe c = charAsIntUnsafe (changeCaseInt c)
 
 changeCaseInt :: Case -> Int -> Int
-changeCaseInt LowerCase i = i + 32
-changeCaseInt UpperCase i = i - 32
+changeCaseInt c i = case c of
+  LowerCase -> i + 32
+  UpperCase -> i - 32
 
 opposite :: Case -> Case
-opposite UpperCase = LowerCase
-opposite LowerCase = UpperCase
+opposite = \case
+  UpperCase -> LowerCase
+  LowerCase -> UpperCase
 
 charAsIntUnsafe :: (Int -> Int) -> (Char -> Char)
 charAsIntUnsafe f = Char.fromIntUnsafe . f . Char.toInt
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,37 +1,37 @@
 module Main (main) where
 
 import ASCII.Case
-
+  ( Case (LowerCase, UpperCase),
+    isCase,
+    letterCase,
+    toCase,
+  )
 import ASCII.Char (Char (..))
-
 import Data.Bool (Bool (..))
-import Data.Function (($))
 import Data.Maybe (Maybe (..))
 import System.IO (IO)
 import Test.Hspec (hspec, it, shouldBe)
 
 main :: IO ()
-main = hspec $ do
-
-    it "letterCase" $ do
-        let f = letterCase
-        f CapitalLetterR `shouldBe` Just UpperCase
-        f SmallLetterR `shouldBe` Just LowerCase
-        f DollarSign `shouldBe` Nothing
-
+main = hspec do
+  it "letterCase" do
+    let f = letterCase
+    f CapitalLetterR `shouldBe` Just UpperCase
+    f SmallLetterR `shouldBe` Just LowerCase
+    f DollarSign `shouldBe` Nothing
 
-    it "isCase UpperCase" $ do
-        let f = isCase UpperCase
-        f CapitalLetterR `shouldBe` True
-        f SmallLetterR `shouldBe` False
-        f DollarSign `shouldBe` False
+  it "isCase UpperCase" do
+    let f = isCase UpperCase
+    f CapitalLetterR `shouldBe` True
+    f SmallLetterR `shouldBe` False
+    f DollarSign `shouldBe` False
 
-    it "toCase UpperCase" $ do
-        let f = toCase UpperCase
-        f SmallLetterX `shouldBe` CapitalLetterX
-        f CapitalLetterA `shouldBe` CapitalLetterA
-        f ExclamationMark `shouldBe` ExclamationMark
+  it "toCase UpperCase" do
+    let f = toCase UpperCase
+    f SmallLetterX `shouldBe` CapitalLetterX
+    f CapitalLetterA `shouldBe` CapitalLetterA
+    f ExclamationMark `shouldBe` ExclamationMark
 
-    it "toCase LowerCase" $ do
-        let f = toCase LowerCase
-        f CapitalLetterF `shouldBe` SmallLetterF
+  it "toCase LowerCase" do
+    let f = toCase LowerCase
+    f CapitalLetterF `shouldBe` SmallLetterF
