diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,18 @@
+0.10.8.0:
+
+  Allow building with GHC 9.10.1 (base 4.20) and (hopefully)
+  avoid warnings about foldl' for all the supported GHC
+  versions.
+
+  Avoid -Wx-partial warning messages when compiling (although
+  the code is not any safer with these changes, it is more
+  obvious when these assumptions are being made). This is only
+  for the src/ directory; the tests/ have not been updated.
+
+  Allow building with filepath 1.5.x and time 1.15 (although
+  not fully tested at this time as not all dependencies have
+  been updated).
+
 0.10.7.0:
 
   Allow building with GHC 9.8.1 (base 4.19).
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -43,8 +43,7 @@
 
     (c) 2003, 2004 G. Klyne
     (c) 2009 Vasili I Galchin
-    (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
-	    2020, 2021, 2022, 2023 Doug Burke
+    (c) 2011 - 2024 Doug Burke
 
 All rights reserved.
 
@@ -83,6 +82,8 @@
 
     % cd swish
     % stack install
+    % STACK_YAML=stack-9.6.yaml stack install
+    % STACK_YAML=stack-9.4.yaml stack install
     % STACK_YAML=stack-9.2.yaml stack install
     % STACK_YAML=stack-9.0.yaml stack install
     % STACK_YAML=stack-8.10.yaml stack install
@@ -92,6 +93,8 @@
     % STACK_YAML=stack-8.2.yaml stack install
     % STACK_YAML=stack-8.0.yaml stack install
     % STACK_YAML=stack-7.10.yaml stack install
+
+I do not guarantee they will all work.
 
 ## With nix
 
diff --git a/flake.lock b/flake.lock
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "nixpkgs": {
       "locked": {
-        "lastModified": 1693145325,
-        "narHash": "sha256-Gat9xskErH1zOcLjYMhSDBo0JTBZKfGS0xJlIRnj6Rc=",
+        "lastModified": 1715499532,
+        "narHash": "sha256-9UJLb8rdi2VokYcfOBQHUzP3iNxOPNWcbK++ENElpk0=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "cddebdb60de376c1bdb7a4e6ee3d98355453fe56",
+        "rev": "af8b9db5c00f1a8e4b83578acc578ff7d823b786",
         "type": "github"
       },
       "original": {
diff --git a/src/Data/Ord/Partial.hs b/src/Data/Ord/Partial.hs
--- a/src/Data/Ord/Partial.hs
+++ b/src/Data/Ord/Partial.hs
@@ -3,7 +3,7 @@
 --------------------------------------------------------------------------------
 -- |
 --  Module      :  Partial
---  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012 Douglas Burke
+--  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -36,7 +36,11 @@
     )
     where
 
-import Data.List (foldl')
+import Data.Foldable (Foldable(..))
+
+-- Avoid messages added in GHC 9.10 about foldl' import from Data.List
+-- being redundant.
+import Prelude hiding (Foldable(..))
 
 ------------------------------------------------------------
 --  Type of partial compare function
diff --git a/src/Swish/GraphClass.hs b/src/Swish/GraphClass.hs
--- a/src/Swish/GraphClass.hs
+++ b/src/Swish/GraphClass.hs
@@ -12,7 +12,7 @@
 -- |
 --  Module      :  GraphClass
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2012, 2016, 2020, 2022 Douglas Burke
+--                 2011, 2012, 2016, 2020, 2022 Douglas, 2024 Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -40,13 +40,17 @@
     )
 where
 
-import Data.Hashable (Hashable(..))
-import Data.List (foldl')
-import Data.Ord (comparing)
-
 import qualified Data.Foldable as F
 import qualified Data.Set as S
 import qualified Data.Traversable as T
+
+import Data.Foldable (Foldable(..))
+import Data.Hashable (Hashable(..))
+import Data.Ord (comparing)
+
+-- Avoid messages added in GHC 9.10 about foldl' import from Data.List
+-- being redundant.
+import Prelude hiding (Foldable(..))
 
 --  NOTE:  I wanted to declare this as a subclass of Functor, but
 --  the constraint on the label type seems to prevent that.
diff --git a/src/Swish/GraphMatch.hs b/src/Swish/GraphMatch.hs
--- a/src/Swish/GraphMatch.hs
+++ b/src/Swish/GraphMatch.hs
@@ -7,7 +7,7 @@
 -- |
 --  Module      :  GraphMatch
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2012, 2016, 2018, 2020, 2022 Douglas Burke
+--                 2011, 2012, 2016, 2018, 2020, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -33,22 +33,27 @@
         graphMatch1, graphMatch2, equivalenceClasses, reclassify
       ) where
 
-import Swish.GraphClass (Arc(..), ArcSet, Label(..))
-import Swish.GraphClass (getComponents, arcLabels, hasLabel, arcToTriple)
+import qualified Data.List as L
+import qualified Data.Map as M
+import qualified Data.Set as S
 
 import Control.Exception.Base (assert)
 import Control.Arrow (second)
 
+import Data.Foldable (Foldable(..))
 import Data.Function (on)
 import Data.Hashable (hashWithSalt)
-import Data.List (foldl', sortBy, groupBy, partition)
+import Data.List (sortBy, groupBy, partition)
 import Data.Ord (comparing)
 import Data.Word
 
-import qualified Data.List as L
-import qualified Data.Map as M
-import qualified Data.Set as S
+-- Avoid messages added in GHC 9.10 about foldl' import from Data.List
+-- being redundant.
+import Prelude hiding (Foldable(..))
 
+import Swish.GraphClass (Arc(..), ArcSet, Label(..))
+import Swish.GraphClass (getComponents, arcLabels, hasLabel, arcToTriple)
+
 --------------------------
 --  Label index value type
 --------------------------
@@ -159,7 +164,8 @@
     where
       -- as is not [] by construction, but would be nice to have
       -- this enforced by the types
-      factor (as, bs) = (head as, bs)
+      factor ([], _) = error "internal error"
+      factor (a:_, bs) = (a, bs)
       eqFirst = (==) `on` fst
 
 ------------------------------------------------------------
@@ -671,7 +677,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2016, 2018, 2020 Douglas Burke
+--    2011, 2012, 2016, 2018, 2020, 2022, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/GraphPartition.hs b/src/Swish/GraphPartition.hs
--- a/src/Swish/GraphPartition.hs
+++ b/src/Swish/GraphPartition.hs
@@ -9,7 +9,7 @@
 --------------------------------------------------------------------------------
 -- |
 --  Module      :  GraphPartition
---  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2022 Douglas Burke
+--  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -29,17 +29,22 @@
     )
 where
 
-import Swish.GraphClass (Label(..), Arc(..))
+import qualified Data.List.NonEmpty as NE
 
 import Control.Monad.State (MonadState(..), State)
 import Control.Monad.State (evalState)
 
-import Data.List (foldl', partition)
+import Data.Foldable (Foldable(..))
+import Data.List (partition)
 import Data.List.NonEmpty (NonEmpty(..), (<|))
 import Data.Maybe (mapMaybe)
 
-import qualified Data.List.NonEmpty as NE
+-- Avoid messages added in GHC 9.10 about foldl' import from Data.List
+-- being redundant.
+import Prelude hiding (Foldable(..))
 
+import Swish.GraphClass (Label(..), Arc(..))
+
 ------------------------------------------------------------
 --  Data type for a partitioned graph
 ------------------------------------------------------------
@@ -252,11 +257,13 @@
     -> PState lb (LabelledPartition lb, [LabelledArcs lb])
 makeStatement (Arc _ prop obj) = do
     intobj <- pickIntSubject obj
-    (gpobj, moresubs) <- if null intobj
-                         then do
-                             ms <- pickVarSubject obj
-                             return (PartObj obj,ms)
-                         else makeStatements (head intobj)
+    (gpobj, moresubs) <-
+      case intobj of
+        (h:_) -> makeStatements h
+        [] -> do
+          ms <- pickVarSubject obj
+          return (PartObj obj,ms)
+
     return ((prop,gpobj), moresubs)
 
 pickNextSubject :: PState lb [LabelledArcs lb]
@@ -585,7 +592,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2022 Douglas Burke
+--    2011, 2012, 2022, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/Monad.hs b/src/Swish/Monad.hs
--- a/src/Swish/Monad.hs
+++ b/src/Swish/Monad.hs
@@ -10,7 +10,7 @@
 -- |
 --  Module      :  Monad
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2012, 2022 Douglas Burke
+--                 2011, 2012, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -161,8 +161,9 @@
 findFormula :: ScopedName -> SwishState -> Maybe RDFFormula
 findFormula nam state = case findGraph nam state of
         Nothing  -> getMaybeContextAxiom nam (nub $ M.elems $ rulesets state)
+        -- does it make sense to allow an empty graph?
         Just []  -> Just $ Formula nam emptyRDFGraph
-        Just grs -> Just $ Formula nam (head grs)
+        Just (gr:_) -> Just $ Formula nam gr
 
 -- | Modify the named rules.
 modRules ::
@@ -248,7 +249,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2022 Douglas Burke 
+--    2011, 2012, 2022, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/Proof.hs b/src/Swish/Proof.hs
--- a/src/Swish/Proof.hs
+++ b/src/Swish/Proof.hs
@@ -10,7 +10,7 @@
 -- |
 --  Module      :  Proof
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2016, 2022 Douglas Burke
+--                 2011, 2016, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -31,15 +31,20 @@
     , checkProof, explainProof, checkStep, showProof, showsProof, showsFormula )
 where
 
-import Swish.Rule (Expression(..), Formula(..), Rule(..))
-import Swish.Rule (showsFormula, showsFormulae)
-import Swish.Ruleset (Ruleset(..))
+import qualified Data.Set as S
 
-import Data.List (union, intersect, intercalate, foldl')
+import Data.Foldable(Foldable(..))
+import Data.List (union, intersect, intercalate)
 import Data.Maybe (catMaybes, isNothing)
 import Data.String.ShowLines (ShowLines(..))
 
-import qualified Data.Set as S
+-- Avoid messages added in GHC 9.10 about foldl' import from Data.List
+-- being redundant.
+import Prelude hiding (Foldable(..))
+
+import Swish.Rule (Expression(..), Formula(..), Rule(..))
+import Swish.Rule (showsFormula, showsFormulae)
+import Swish.Ruleset (Ruleset(..))
 
 ------------------------------------------------------------
 --  Proof framework
diff --git a/src/Swish/RDF/BuiltIn/Rules.hs b/src/Swish/RDF/BuiltIn/Rules.hs
--- a/src/Swish/RDF/BuiltIn/Rules.hs
+++ b/src/Swish/RDF/BuiltIn/Rules.hs
@@ -3,7 +3,7 @@
 --------------------------------------------------------------------------------
 -- |
 --  Module      :  Rules
---  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2022 Douglas Burke
+--  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -64,16 +64,20 @@
     , filter2 varFilterNE
     ]
     where
-      -- Swish.RDF.VarBinding.openVbmName seems to require that the label
-      -- list not be evaluated which means that we can not replace these
-      -- statements by ones like
-      --
-      --    filter1 f (lb:_) = makeVarFilterModift $ f lb
+      -- Swish.VarBinding.openVbmName seems to require that the label
+      -- list not be evaluated which means that we end up delaying
+      -- the evaluation of the list as long as possible (i.e. when
+      -- evaluating the arguments for `f`).
       --
-      filter1 f lbs = makeVarFilterModify $ f (head lbs)
-      filter2 f lbs = makeVarFilterModify $ f (head lbs) (lbs !! 1)
-      -- filterN f lbs = makeVarFilterModify $ f ...
+      filter1 f lbs = makeVarFilterModify . f $ case lbs of
+        (lb:_) -> lb
+        [] -> error "unexpected empty list"
 
+      filter2 f lbs = makeVarFilterModify . uncurry f $ case lbs of
+        (lb1:lb2:_) -> (lb1, lb2)
+        _ -> error "requires at least 2 elements in the list"
+
+
 ------------------------------------------------------------
 --  Declare variable binding modifiers map
 ------------------------------------------------------------
@@ -132,7 +136,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2022 Douglas Burke
+--    2011, 2012, 2022, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/RDF/ClassRestrictionRule.hs b/src/Swish/RDF/ClassRestrictionRule.hs
--- a/src/Swish/RDF/ClassRestrictionRule.hs
+++ b/src/Swish/RDF/ClassRestrictionRule.hs
@@ -7,7 +7,7 @@
 -- |
 --  Module      :  ClassRestrictionRule
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2012, 2014, 2018, 2022 Douglas Burke
+--                 2011, 2012, 2014, 2018, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -478,7 +478,7 @@
 coverSets pvs dts =
     minima partCompareListSubset $ map (map fst) ctss
     where
-        ctss = filter coverspvs $ tail $ subsequences cts
+        ctss = filter coverspvs $ drop 1 $ subsequences cts
         cts  = minima (partComparePair partCompareListMaybe partCompareEq) dts
         coverspvs cs = coversVals delete (map snd cs) pvs
 
@@ -529,7 +529,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2014, 2018, 2022 Douglas Burke
+--    2011, 2012, 2014, 2018, 2022, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/RDF/Datatype/XSD/Decimal.hs b/src/Swish/RDF/Datatype/XSD/Decimal.hs
--- a/src/Swish/RDF/Datatype/XSD/Decimal.hs
+++ b/src/Swish/RDF/Datatype/XSD/Decimal.hs
@@ -7,7 +7,7 @@
 -- |
 --  Module      :  Decimal
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                     2011 William Waites, 2011, 2012, 2014, 2022 Douglas Burke
+--                     2011 William Waites, 2011, 2012, 2014, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -195,11 +195,13 @@
     , ( (>= 0),     [ ] )
     ]
 
-liftL2 :: (a->a->Bool) -> ([a]->a) -> ([a]->a) -> [a] -> Bool
-liftL2 p i1 i2 as = p (i1 as) (i2 as)
+lcomp ::
+  (a -> a -> Bool)
+  -> [a] -- ^ this list must have at least two elements
+  -> Bool
+lcomp p (a1:a2:_) = p a1 a2
+lcomp _ _ = error "internal error"
 
-lcomp :: (a->a->Bool) -> [a] -> Bool
-lcomp p = liftL2 p head (head . tail)
 
 -- eq
 
@@ -466,7 +468,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                2011 William Waites, 2011, 2012, 2014, 2022 Douglas Burke, 
+--                2011 William Waites, 2011, 2012, 2014, 2022, 2024 Douglas Burke,
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/RDF/Datatype/XSD/Integer.hs b/src/Swish/RDF/Datatype/XSD/Integer.hs
--- a/src/Swish/RDF/Datatype/XSD/Integer.hs
+++ b/src/Swish/RDF/Datatype/XSD/Integer.hs
@@ -6,7 +6,7 @@
 --------------------------------------------------------------------------------
 -- |
 --  Module      :  Integer
---  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2014, 2018, 2022 Douglas Burke
+--  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2014, 2018, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -228,11 +228,13 @@
     , ( (>= 0),     [ ] )
     ]
 
-liftL2 :: (a->a->Bool) -> ([a]->a) -> ([a]->a) -> [a] -> Bool
-liftL2 p i1 i2 as = p (i1 as) (i2 as)
+lcomp ::
+  (a -> a -> Bool)
+  -> [a] -- ^ this list must have at least two elements
+  -> Bool
+lcomp p (a1:a2:_) = p a1 a2
+lcomp _ _ = error "internal error"
 
-lcomp :: (a->a->Bool) -> [a] -> Bool
-lcomp p = liftL2 p head (head . tail)
 
 -- eq
 
@@ -510,7 +512,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2014, 2018, 2022 Douglas Burke
+--    2011, 2012, 2014, 2018, 2022, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/RDF/Datatype/XSD/String.hs b/src/Swish/RDF/Datatype/XSD/String.hs
--- a/src/Swish/RDF/Datatype/XSD/String.hs
+++ b/src/Swish/RDF/Datatype/XSD/String.hs
@@ -6,7 +6,7 @@
 --------------------------------------------------------------------------------
 -- |
 --  Module      :  String
---  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2014 Douglas Burke
+--  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2014, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -150,11 +150,13 @@
     }
 -}
 
-liftL2 :: (a->a->Bool) -> ([a]->a) -> ([a]->a) -> [a] -> Bool
-liftL2 p i1 i2 as = p (i1 as) (i2 as)
+lcomp ::
+  (a -> a -> Bool)
+  -> [a] -- ^ this list must have at least two elements
+  -> Bool
+lcomp p (a1:a2:_) = p a1 a2
+lcomp _ _ = error "internal error"
 
-lcomp :: (a->a->Bool) -> [a] -> Bool
-lcomp p = liftL2 p head (head . tail)
 
 -- eq
 
@@ -307,7 +309,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012 Douglas Burke
+--    2011, 2012, 2014, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/RDF/Formatter/Internal.hs b/src/Swish/RDF/Formatter/Internal.hs
--- a/src/Swish/RDF/Formatter/Internal.hs
+++ b/src/Swish/RDF/Formatter/Internal.hs
@@ -11,7 +11,7 @@
 -- |
 --  Module      :  Internal
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2012, 2013, 2014, 2016, 2018, 2020, 2022 Douglas Burke
+--                 2011 - 2014, 2016, 2018, 2020, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -80,7 +80,9 @@
 
 import Control.Monad.State (State, get, gets, modify, put)
 
-import Data.List (foldl', groupBy, intersperse, partition)
+import Data.Foldable(Foldable(..))
+import Data.Function (on)
+import Data.List (groupBy, intersperse, partition)
 import Data.Maybe (isJust)
 #if (!defined(__GLASGOW_HASKELL__)) || (__GLASGOW_HASKELL__ < 710)
 import Data.Monoid (Monoid(..), mconcat)
@@ -90,6 +92,11 @@
 
 import Network.URI (URI)
 
+-- Avoid messages added in GHC 9.10 about foldl' import from Data.List
+-- being redundant.
+import Prelude hiding (Foldable(..))
+
+
 findPrefix :: URI -> M.Map a URI -> Maybe a
 findPrefix u = M.lookup u . M.fromList . map swap . M.assocs
 
@@ -255,23 +262,19 @@
 arcTree :: (Eq lb) => SortedArcs lb -> SubjTree lb
 arcTree (SA as) = commonFstEq (commonFstEq id) $ map spopair as
     where
-        spopair (Arc s p o) = (s,(p,o))
-
-{-
-arcTree as = map spopair $ sort as
-    where
-        spopair (Arc s p o) = (s,[(p,[o])])
--}
+        spopair (Arc s p o) = (s, (p,o))
 
 --  Rearrange a list of pairs so that multiple occurrences of the first
 --  are commoned up, and the supplied function is applied to each sublist
 --  with common first elements to obtain the corresponding second value
 commonFstEq :: (Eq a) => ( [b] -> c ) -> [(a,b)] -> [(a,c)]
-commonFstEq f ps =
-    [ (fst $ head sps,f $ map snd sps) | sps <- groupBy fstEq ps ]
-    where
-        fstEq (f1,_) (f2,_) = f1 == f2
+commonFstEq f ps = map conv (groupBy fstEq ps)
+  where
+    fstEq = (==) `on` fst
 
+    conv [] = error "internal error"
+    conv sps@((h, _) : _) = (h, f (map snd sps))
+
 {-
 -- Diagnostic code for checking arcTree logic:
 testArcTree = (arcTree testArcTree1) == testArcTree2
@@ -709,7 +712,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2013, 2014, 2016, 2018, 2020, 2022 Douglas Burke
+--    2011 - 2014, 2016, 2018, 2020, 2022, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/RDF/Graph.hs b/src/Swish/RDF/Graph.hs
--- a/src/Swish/RDF/Graph.hs
+++ b/src/Swish/RDF/Graph.hs
@@ -9,7 +9,7 @@
 -- |
 --  Module      :  Graph
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2020. 2022 Douglas Burke
+--                 2011 - 2016, 2018, 2020. 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -163,6 +163,48 @@
     )
     where
 
+import qualified Data.Map as M
+import qualified Data.Set as S
+import qualified Data.Text as T
+import qualified Data.Text.Read as T
+import qualified Data.Traversable as Traversable
+
+#if (!defined(__GLASGOW_HASKELL__)) || (__GLASGOW_HASKELL__ < 710)
+import Control.Applicative (Applicative(pure), (<$>), (<*>))
+import Data.Monoid (Monoid(..))
+#endif
+
+import Control.Arrow ((***))
+
+import Data.Char (ord, isDigit)
+import Data.Foldable (Foldable(..))
+import Data.Hashable (hashWithSalt)
+import Data.List (intersect, union)
+import Data.Maybe (mapMaybe)
+-- import Data.Ord (comparing)
+import Data.Word (Word32)
+
+import Data.String (IsString(..))
+
+#if MIN_VERSION_time(1,5,0)
+import Data.Time (UTCTime, Day, ParseTime, parseTimeM, formatTime, defaultTimeLocale)
+#else
+import Data.Time (UTCTime, Day, ParseTime, parseTime, formatTime)
+import System.Locale (defaultTimeLocale)
+#endif
+
+#if !(MIN_VERSION_base(4, 11, 0))
+import Data.Semigroup
+#endif
+
+import Network.URI (URI)
+
+import Text.Printf
+
+-- Avoid messages added in GHC 9.10 about foldl' import from Data.List
+-- being redundant.
+import Prelude hiding (Foldable(..))
+
 import Swish.Namespace
     ( getNamespaceTuple
     , getScopedNameURI
@@ -196,43 +238,7 @@
 import Swish.GraphMatch (graphMatch)
 import Swish.QName (QName, getLName)
 
-#if (!defined(__GLASGOW_HASKELL__)) || (__GLASGOW_HASKELL__ < 710)
-import Control.Applicative (Applicative(pure), (<$>), (<*>))
-import Data.Monoid (Monoid(..))
-#endif
 
-import Control.Arrow ((***))
-
-import Network.URI (URI)
-
-import Data.Maybe (mapMaybe)
-import Data.Char (ord, isDigit)
-import Data.Hashable (hashWithSalt)
-import Data.List (intersect, union, foldl')
--- import Data.Ord (comparing)
-import Data.Word (Word32)
-
-import Data.String (IsString(..))
-
-#if MIN_VERSION_time(1,5,0)
-import Data.Time (UTCTime, Day, ParseTime, parseTimeM, formatTime, defaultTimeLocale)
-#else
-import Data.Time (UTCTime, Day, ParseTime, parseTime, formatTime)
-import System.Locale (defaultTimeLocale)  
-#endif
-
-#if !(MIN_VERSION_base(4, 11, 0))
-import Data.Semigroup
-#endif
-
-import Text.Printf
-
-import qualified Data.Map as M
-import qualified Data.Set as S
-import qualified Data.Text as T
-import qualified Data.Text.Read as T
-import qualified Data.Traversable as Traversable
-
 -- | RDF graph node values
 --
 --  cf. <http://www.w3.org/TR/rdf-concepts/#section-Graph-syntax> version 1.0
@@ -1532,8 +1538,11 @@
 --
 newNode :: (Label lb) => lb -> [lb] -> lb
 newNode dn existnodes =
-    head $ newNodes dn existnodes
+  case newNodes dn existnodes of
+    (n:_) -> n
+    [] -> error "unable to create a new node; should be impossible"
 
+
 -- |Given a node and a list of existing nodes, generate a list of new
 --  nodes for the supplied node that do not clash with any existing node.
 newNodes :: (Label lb) => lb -> [lb] -> [lb]
@@ -1551,7 +1560,8 @@
 -}
 
 noderootindex :: (Label lb) => lb -> (String, Word32)
-noderootindex dn = (nh,nx) where
+noderootindex dn = (nh,nx)
+  where
     (nh,nt) = splitnodeid $ getLocal dn
     nx      = if null nt then 0 else read nt
 
@@ -1561,10 +1571,6 @@
 trynodes :: (Label lb) => (String, Word32) -> [lb]
 trynodes (nr,nx) = [ makeLabel (nr ++ show n) | n <- iterate (+ 1) nx ]
 
-{-
-trybnodes :: (Label lb) => (String,Int) -> [lb]
-trybnodes (nr,nx) = [ makeLabel (nr++show n) | n <- iterate (+1) nx ]
--}
 
 -- | Memory-based RDF graph type
 
@@ -1619,7 +1625,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2013, 2014, 2015, 2016, 2018, 2020, 2022 Douglas Burke
+--    2011 - 2016, 2018, 2020, 2022, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/RDF/Proof.hs b/src/Swish/RDF/Proof.hs
--- a/src/Swish/RDF/Proof.hs
+++ b/src/Swish/RDF/Proof.hs
@@ -8,7 +8,7 @@
 -- |
 --  Module      :  Proof
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2012, 2014, 2016 Douglas Burke
+--                 2011, 2012, 2014, 2016, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -171,17 +171,20 @@
         --  Merge antecedents to single graph, renaming bnodes if needed.
         --  (Null test and using 'foldl1' to avoid merging if possible.)
         mergeGraph  = if null ante then mempty
-                        else foldl1 merge ante
+                      else foldl1 merge ante
+
         --  Obtain lists of variable and non-variable nodes
         --  (was: nonvarNodes = allLabels (not . labelIsVar) mergeGraph)
         nonvarNodes = vocab
         varNodes    = S.toList $ allLabels labelIsVar mergeGraph
+
         --  Obtain list of possible remappings for non-variable nodes
         mapList     = remapLabelList nonvarNodes varNodes
-        mapSubLists = (tail . subsequences) mapList
+        mapSubLists = (drop 1 . subsequences) mapList
         mapGr ls = fmapNSGraph 
                    (\l -> M.findWithDefault l l
                           (M.fromList ls))
+
     in
         --  Return all remappings of the original merged graph
         flist (map mapGr mapSubLists) mergeGraph
@@ -305,11 +308,14 @@
         --  Merge antecedents to single graph, renaming bnodes if needed.
         --  (Null test and using 'foldl1' to avoid merging if possible.)
         mergeGraph  = if null ante then mempty
-                        else foldl1 merge ante
+                      else foldl1 merge ante
+
+        list = init $ drop 1 $ subsequences $ S.toList $ getArcs mergeGraph
+
     in
         --  Return all subgraphs of the full graph constructed above
         -- TODO: update to use sets as appropriate
-        map (setArcs mergeGraph . S.fromList) (init $ tail $ subsequences $ S.toList $ getArcs mergeGraph)
+        map (setArcs mergeGraph . S.fromList) list
 
 --  Subgraph entailment inference checker
 --
@@ -362,7 +368,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012 Douglas Burke  
+--    2011, 2012, 2014, 2016, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/RDF/Ruleset.hs b/src/Swish/RDF/Ruleset.hs
--- a/src/Swish/RDF/Ruleset.hs
+++ b/src/Swish/RDF/Ruleset.hs
@@ -7,7 +7,7 @@
 -- |
 --  Module      :  Ruleset
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---                 2011, 2012, 2014, 2016 Douglas Burke
+--                 2011, 2012, 2014, 2016, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -516,10 +516,17 @@
         app       = applyVarBinding
         alocnodes = zip (nub $ flist (map app vars) alocvar)
                         (newNodes (makeBlank bindvar) exbnode)
-        newvb var = joinVarBindings
-            ( makeVarBinding $ head
-              [ [(bindvar,b)] | (v,b) <- alocnodes, app var alocvar == v ] )
-            var
+
+
+        tlist var = [ [(bindvar, b)] |
+                      (v,b) <- alocnodes,
+                      app var alocvar == v ]
+        hlist var = case tlist var of
+          (h:_) -> h
+          _ -> error "internal error"
+
+        newvb var = joinVarBindings (makeVarBinding (hlist var)) var
+
     in
         map newvb vars
 
@@ -527,7 +534,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012 Douglas Burke  
+--    2011, 2012, 2014, 2016, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/Script.hs b/src/Swish/Script.hs
--- a/src/Swish/Script.hs
+++ b/src/Swish/Script.hs
@@ -6,7 +6,7 @@
 --------------------------------------------------------------------------------
 {- |
 Module      :  Script
-Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2014, 2018, 2020 Douglas Burke
+Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2014, 2018, 2020, 2024 Douglas Burke
 License     :  GPL V2
 
 Maintainer  :  Douglas Burke
@@ -475,7 +475,13 @@
             }
 
 ssGetGraph :: ScopedName -> SwishStateIO (Either String RDFGraph)
-ssGetGraph nam = fmap head <$> ssGetList nam
+ssGetGraph nam = do
+  grs <- ssGetList nam
+  pure $ case grs of
+           Left emsg -> Left emsg
+           -- Does it make sense to allow the empty graph?
+           Right [] -> Left ("Graph or list is empty: " ++ show nam)
+           Right (gr:_) -> Right gr
   
 ssGetFormula :: ScopedName -> SwishStateIO (Either String RDFFormula)
 ssGetFormula nam = gets find
@@ -1481,7 +1487,7 @@
 --------------------------------------------------------------------------------
 --
 --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
---    2011, 2012, 2014, 2018, 2020 Douglas Burke
+--    2011, 2012, 2014, 2018, 2020, 2024 Douglas Burke
 --  All rights reserved.
 --
 --  This file is part of Swish.
diff --git a/src/Swish/VarBinding.hs b/src/Swish/VarBinding.hs
--- a/src/Swish/VarBinding.hs
+++ b/src/Swish/VarBinding.hs
@@ -8,7 +8,7 @@
 -- |
 --  Module      :  VarBinding
 --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 
---                 2011, 2012, 2014, 2015, 2016, 2018, 2020, 2022 Douglas Burke
+--                 2011, 2012, 2014, 2015, 2016, 2018, 2020, 2022, 2024 Douglas Burke
 --  License     :  GPL V2
 --
 --  Maintainer  :  Douglas Burke
@@ -41,12 +41,8 @@
     )
 where
 
-import Swish.Namespace (ScopedName, getScopeLocal)
-import Swish.QName (newLName, getLName)
-
-import Swish.RDF.Vocabulary (swishName)
-
-import Swish.Utils.ListHelpers (flist)
+import qualified Data.Map as M
+import qualified Data.Set as S
 
 #if (!defined(__GLASGOW_HASKELL__)) || (__GLASGOW_HASKELL__ < 710)
 import Control.Applicative ((<$>), (<*>))
@@ -59,15 +55,22 @@
 
 import Control.Monad (mplus)
 
+import Data.Foldable(Foldable(..))
 import Data.Function (on)
-import Data.List (find, intersect, union, (\\), foldl', permutations)
+import Data.List (find, intersect, union, (\\), permutations)
 import Data.Maybe (mapMaybe, fromMaybe, isJust, fromJust, listToMaybe)
 import Data.Ord (comparing)
 
-import qualified Data.Map as M
-import qualified Data.Set as S
+-- Avoid messages added in GHC 9.10 about foldl' import from Data.List
+-- being redundant.
+import Prelude hiding (Foldable(..))
 
--- import Prelude
+import Swish.Namespace (ScopedName, getScopeLocal)
+import Swish.QName (newLName, getLName)
+
+import Swish.RDF.Vocabulary (swishName)
+
+import Swish.Utils.ListHelpers (flist)
 
 ------------------------------------------------------------
 --  Query variable bindings
diff --git a/swish.cabal b/swish.cabal
--- a/swish.cabal
+++ b/swish.cabal
@@ -1,12 +1,12 @@
 Cabal-Version:      2.4
 
 Name:               swish
-Version:            0.10.7.0
+Version:            0.10.8.0
 Stability:          experimental
 License:            LGPL-2.1-or-later
 License-file:       LICENSE 
 Author:             Graham Klyne - GK@ninebynine.org
-Copyright:          (c) 2003, 2004 G. Klyne; 2009 Vasili I Galchin; 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Doug Burke; All rights reserved.
+Copyright:          (c) 2003, 2004 G. Klyne; 2009 Vasili I Galchin; 2011 - 2024 Doug Burke; All rights reserved.
 Maintainer:         dburke@cfa.harvard.edu
 Category:           Semantic Web
 Synopsis:           A semantic web toolkit. 
@@ -97,19 +97,19 @@
 Library
    Default-Language:    Haskell2010
    Build-Depends:
-      base >= 4.8 && < 4.20,
+      base >= 4.8 && < 4.21,
       containers >= 0.5 && < 0.8,
       directory >= 1.0 && < 1.4,
-      filepath >= 1.1 && < 1.5,
+      filepath >= 1.1 && < 1.6,
       -- Early versions of hashable 1.2 are problematic
-      hashable (>= 1.1 && < 1.2) || (>= 1.2.0.6 && <1.5),
+      hashable (>= 1.1 && < 1.2) || (>= 1.2.0.6 && < 1.5),
       intern >= 0.8 && < 1.0,
       mtl >= 2 && < 3,
       polyparse >= 1.6 && < 1.14,
       text >= 0.11 && < 2.2,
       -- I don't think 1.9.0 will work and it was quickly replaced
       -- so do not support it           
-      time (>= 1.5 && < 1.9) || (>= 1.9.1 && < 1.14)
+      time (>= 1.5 && < 1.9) || (>= 1.9.1 && < 1.15)
 
    if flag(network-uri)
      build-depends: network-uri >= 2.6 && < 2.8
