diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,7 @@
 Changelog for CmdArgs
 
+0.10.22, released 2023-03-13
+    #68, support GHC 9.6
 0.10.21, released 2021-02-14
     Handle GHC 9.0 optimisations
     Remove support for GHC 7.4 to 7.8
diff --git a/Data/Generics/Any/Prelude.hs b/Data/Generics/Any/Prelude.hs
--- a/Data/Generics/Any/Prelude.hs
+++ b/Data/Generics/Any/Prelude.hs
@@ -46,7 +46,9 @@
 
 
 isString x = typeName x == "[Char]"
-isList x = typeShell x == "[]"
+-- GHC 9.6 changes from [] to List, so accept either
+isList x = ts == "[]" || ts == "List"
+    where ts = typeShell x
 isMaybe x = typeShell x == "Maybe"
 isTuple x = isJust $ readTupleType $ typeShell x
 
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Neil Mitchell 2009-2021.
+Copyright Neil Mitchell 2009-2023.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# CmdArgs: Easy Command Line Processing [![Hackage version](https://img.shields.io/hackage/v/cmdargs.svg?label=Hackage)](https://hackage.haskell.org/package/cmdargs) [![Stackage version](https://www.stackage.org/package/cmdargs/badge/nightly?label=Stackage)](https://www.stackage.org/package/cmdargs) [![Build status](https://img.shields.io/github/workflow/status/ndmitchell/cmdargs/ci.svg)](https://github.com/ndmitchell/cmdargs/actions)
+# CmdArgs: Easy Command Line Processing [![Hackage version](https://img.shields.io/hackage/v/cmdargs.svg?label=Hackage)](https://hackage.haskell.org/package/cmdargs) [![Stackage version](https://www.stackage.org/package/cmdargs/badge/nightly?label=Stackage)](https://www.stackage.org/package/cmdargs) [![Build status](https://img.shields.io/github/workflow/status/ndmitchell/cmdargs/ci/master.svg)](https://github.com/ndmitchell/cmdargs/actions)
 
 CmdArgs is a Haskell library for defining command line parsers. The two features that make it a better choice than the standard [getopt library](http://haskell.org/ghc/docs/latest/html/libraries/base/System-Console-GetOpt.html) are:
 
@@ -16,10 +16,10 @@
 ```
 Despite being very concise, this processor is already fairly well featured:
 
-    $ runhaskell Sample.hs --hello=world
+    $ runghc Sample.hs --hello=world
     Sample {hello = "world"}
 
-    $ runhaskell Sample.hs --help
+    $ runghc Sample.hs --help
     Sample v1, (C) Neil Mitchell 2009
 
     sample [FLAG]
@@ -67,13 +67,13 @@
 
 Now we have a reasonably functional command line argument processor. Some sample interactions are:
 
-    $ runhaskell Sample.hs --hello=world
+    $ runghc Sample.hs --hello=world
     Sample {hello = "world"}
 
-    $ runhaskell Sample.hs --version
+    $ runghc Sample.hs --version
     The sample program
 
-    $ runhaskell Sample.hs --help
+    $ runghc Sample.hs --help
     The sample program
 
     sample [OPTIONS]
@@ -116,13 +116,13 @@
 ```
 Compared to the first example, we now have multiple constructors, and a sample value for each constructor is passed to `cmdArgs`. Some sample interactions with this command line are:
 
-    $ runhaskell Sample.hs hello --whom=world
+    $ runghc Sample.hs hello --whom=world
     Hello {whom = "world"}
 
-    $ runhaskell Sample.hs goodbye
+    $ runghc Sample.hs goodbye
     Goodbye
 
-    $ runhaskell Sample.hs --help
+    $ runghc Sample.hs --help
     The sample program
 
     sample [OPTIONS]
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,4 +1,2 @@
-#! /usr/bin/runhaskell
-
 import Distribution.Simple
 main = defaultMain
diff --git a/System/Console/CmdArgs/Explicit.hs b/System/Console/CmdArgs/Explicit.hs
--- a/System/Console/CmdArgs/Explicit.hs
+++ b/System/Console/CmdArgs/Explicit.hs
@@ -173,7 +173,7 @@
             Right (a,b) -> Right $ f a b v
 
         format :: String -> Either String (HelpFormat,TextFormat)
-        format xs = foldl (\acc x -> either Left (f x) acc) (Right def) (sep xs)
+        format xs = foldl (\acc x -> f x =<< acc) (Right def) (sep xs)
             where
                 sep = words . map (\x -> if x `elem` ":," then ' ' else toLower x)
                 f x (a,b) = case x of
diff --git a/System/Console/CmdArgs/Explicit/Process.hs b/System/Console/CmdArgs/Explicit/Process.hs
--- a/System/Console/CmdArgs/Explicit/Process.hs
+++ b/System/Console/CmdArgs/Explicit/Process.hs
@@ -23,7 +23,7 @@
             | null (fst $ modeArgs m) && isNothing (snd $ modeArgs m) && args /= [] &&
               not (null $ modeModes m) && not ("-" `isPrefixOf` concat args)
                 -> Left $ missing "mode" $ concatMap modeNames $ modeModes m
-            | otherwise -> either Left (modeCheck m) $ processFlags m (modeValue m) args
+            | otherwise -> modeCheck m =<< processFlags m (modeValue m) args
     where
         (find,a,as) = case args of
             [] -> (NotFound,"",[])
diff --git a/System/Console/CmdArgs/Test/SplitJoin.hs b/System/Console/CmdArgs/Test/SplitJoin.hs
--- a/System/Console/CmdArgs/Test/SplitJoin.hs
+++ b/System/Console/CmdArgs/Test/SplitJoin.hs
@@ -28,7 +28,7 @@
     writeFile src "import System.Environment\nmain = print =<< getArgs\n"
     quickCheckWith stdArgs{chatty=False} $ \(CmdLine x) -> unsafePerformIO $ do
         putStr $ ",(,) " ++ (show x) ++ " "
-        system $ "runhaskell \"" ++ src ++ "\" " ++ x
+        system $ "runghc \"" ++ src ++ "\" " ++ x
         return True
 
 
diff --git a/cmdargs.cabal b/cmdargs.cabal
--- a/cmdargs.cabal
+++ b/cmdargs.cabal
@@ -1,13 +1,13 @@
-cabal-version:      >= 1.18
+cabal-version:      1.18
 build-type:         Simple
 name:               cmdargs
-version:            0.10.21
+version:            0.10.22
 license:            BSD3
 license-file:       LICENSE
 category:           Console
 author:             Neil Mitchell <ndmitchell@gmail.com>
 maintainer:         Neil Mitchell <ndmitchell@gmail.com>
-copyright:          Neil Mitchell 2009-2021
+copyright:          Neil Mitchell 2009-2023
 synopsis:           Command line argument processing
 description:
     This library provides an easy way to define command line parsers. Most users
@@ -33,7 +33,7 @@
 extra-doc-files:
     README.md
     CHANGES.txt
-tested-with:        GHC==9.0, GHC==8.10, GHC==8.8, GHC==8.6, GHC==8.4, GHC==8.2, GHC==8.0
+tested-with:        GHC==9.2, GHC==9.0, GHC==8.10, GHC==8.8, GHC==8.6, GHC==8.4, GHC==8.2, GHC==8.0
 
 source-repository head
     type:     git
