diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,9 @@
 Changelog for Extra
 
+1.7.13, released 2023-04-22
+    #102, add mwhen :: Monoid a => Bool -> a -> a
+    #99, make replace with an empty from intersperse the replacement
+    #101, future-proof against addition of Data.List.!?
 1.7.12, released 2022-09-02
     #98, make both lazy in its argument
     #98, make first3,second3,third3 lazy in their argument
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Neil Mitchell 2014-2022.
+Copyright Neil Mitchell 2014-2023.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/extra.cabal b/extra.cabal
--- a/extra.cabal
+++ b/extra.cabal
@@ -1,13 +1,13 @@
 cabal-version:      1.18
 build-type:         Simple
 name:               extra
-version:            1.7.12
+version:            1.7.13
 license:            BSD3
 license-file:       LICENSE
 category:           Development
 author:             Neil Mitchell <ndmitchell@gmail.com>
 maintainer:         Neil Mitchell <ndmitchell@gmail.com>
-copyright:          Neil Mitchell 2014-2022
+copyright:          Neil Mitchell 2014-2023
 synopsis:           Extra functions I use.
 description:
     A library of extra functions for the standard Haskell libraries. Most functions are simple additions, filling out missing functionality. A few functions are available in later versions of GHC, but this package makes them available back to GHC 7.2.
@@ -15,7 +15,7 @@
     The module "Extra" documents all functions provided by this library. Modules such as "Data.List.Extra" provide extra functions over "Data.List" and also reexport "Data.List". Users are recommended to replace "Data.List" imports with "Data.List.Extra" if they need the extra functionality.
 homepage:           https://github.com/ndmitchell/extra#readme
 bug-reports:        https://github.com/ndmitchell/extra/issues
-tested-with:        GHC==9.0, GHC==8.10, GHC==8.8, GHC==8.6
+tested-with:        GHC==9.2, GHC==9.0, GHC==8.10, GHC==8.8, GHC==8.6
 
 extra-doc-files:
     CHANGES.txt
@@ -52,6 +52,7 @@
         Data.IORef.Extra
         Data.List.Extra
         Data.List.NonEmpty.Extra
+        Data.Monoid.Extra
         Data.Tuple.Extra
         Data.Typeable.Extra
         Data.Version.Extra
diff --git a/src/Data/List/Extra.hs b/src/Data/List/Extra.hs
--- a/src/Data/List/Extra.hs
+++ b/src/Data/List/Extra.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TupleSections, ConstraintKinds #-}
+{-# LANGUAGE CPP, TupleSections, ConstraintKinds #-}
 
 -- | This module extends "Data.List" with extra functions of a similar nature.
 --   The package also exports the existing "Data.List" functions.
@@ -156,6 +156,7 @@
 lastDef d xs = foldl (\_ x -> x) d xs -- I know this looks weird, but apparently this is the fastest way to do this: https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.List.html#last
 {-# INLINE lastDef #-}
 
+#if !MIN_VERSION_base(4,19,0)
 -- | A total variant of the list index function `(!!)`.
 --
 -- > [2,3,4] !? 1    == Just 3
@@ -169,6 +170,7 @@
                                    0 -> Just x
                                    _ -> r (k-1)) (const Nothing) xs n
 {-# INLINABLE (!?) #-}
+#endif
 
 -- | A composition of 'not' and 'null'.
 --
@@ -549,15 +551,17 @@
     | otherwise = y : mergeBy f (x:xs) ys
 
 
--- | Replace a subsequence everywhere it occurs. The first argument must
---   not be the empty list.
+-- | Replace a subsequence everywhere it occurs.
 --
 -- > replace "el" "_" "Hello Bella" == "H_lo B_la"
 -- > replace "el" "e" "Hello"       == "Helo"
--- > replace "" "e" "Hello"         == undefined
--- > \xs ys -> not (null xs) ==> replace xs xs ys == ys
-replace :: (Partial, Eq a) => [a] -> [a] -> [a] -> [a]
-replace [] _ _ = error "Extra.replace, first argument cannot be empty"
+-- > replace "" "x" "Hello"         == "xHxexlxlxox"
+-- > replace "" "x" ""              == "x"
+-- > \xs ys -> replace xs xs ys == ys
+replace :: Eq a => [a] -> [a] -> [a] -> [a]
+replace [] to xs = go xs
+    where go [] = to
+          go (x:xs) = to ++ x : go xs
 replace from to xs | Just xs <- stripPrefix from xs = to ++ replace from to xs
 replace from to (x:xs) = x : replace from to xs
 replace from to [] = []
diff --git a/src/Data/Monoid/Extra.hs b/src/Data/Monoid/Extra.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Monoid/Extra.hs
@@ -0,0 +1,17 @@
+
+-- | Extra functions for working with monoids.
+module Data.Monoid.Extra(
+    module Data.Monoid,
+    -- * Extra operations
+    mwhen
+    ) where
+
+import Data.Monoid
+
+-- | Like 'Control.Monad.when', but operating on a 'Monoid'. If the first argument
+--   is 'True' returns the second, otherwise returns 'mempty'.
+--
+-- > mwhen True  "test" == "test"
+-- > mwhen False "test" == ""
+mwhen :: Monoid a => Bool -> a -> a
+mwhen b x = if b then x else mempty
diff --git a/src/Extra.hs b/src/Extra.hs
--- a/src/Extra.hs
+++ b/src/Extra.hs
@@ -27,6 +27,9 @@
     -- * Data.List.NonEmpty.Extra
     -- | Extra functions available in @"Data.List.NonEmpty.Extra"@.
     (|:), (|>), appendl, appendr, maximum1, minimum1, maximumBy1, minimumBy1, maximumOn1, minimumOn1,
+    -- * Data.Monoid.Extra
+    -- | Extra functions available in @"Data.Monoid.Extra"@.
+    mwhen,
     -- * Data.Tuple.Extra
     -- | Extra functions available in @"Data.Tuple.Extra"@.
     first, second, (***), (&&&), dupe, both, firstM, secondM, fst3, snd3, thd3, first3, second3, third3, curry3, uncurry3,
@@ -60,6 +63,7 @@
 import Data.IORef.Extra
 import Data.List.Extra
 import Data.List.NonEmpty.Extra hiding (cons, snoc, sortOn, union, unionBy, nubOrd, nubOrdBy, nubOrdOn, (!?), foldl1', repeatedly)
+import Data.Monoid.Extra
 import Data.Tuple.Extra
 import Data.Version.Extra
 import Numeric.Extra
diff --git a/test/TestGen.hs b/test/TestGen.hs
--- a/test/TestGen.hs
+++ b/test/TestGen.hs
@@ -190,8 +190,9 @@
     testGen "\\xs ys -> merge (sort xs) (sort ys) == sort (xs ++ ys)" $ \xs ys -> merge (sort xs) (sort ys) == sort (xs ++ ys)
     testGen "replace \"el\" \"_\" \"Hello Bella\" == \"H_lo B_la\"" $ replace "el" "_" "Hello Bella" == "H_lo B_la"
     testGen "replace \"el\" \"e\" \"Hello\"       == \"Helo\"" $ replace "el" "e" "Hello"       == "Helo"
-    testGen "replace \"\" \"e\" \"Hello\"         == undefined" $ erroneous $ replace "" "e" "Hello"
-    testGen "\\xs ys -> not (null xs) ==> replace xs xs ys == ys" $ \xs ys -> not (null xs) ==> replace xs xs ys == ys
+    testGen "replace \"\" \"x\" \"Hello\"         == \"xHxexlxlxox\"" $ replace "" "x" "Hello"         == "xHxexlxlxox"
+    testGen "replace \"\" \"x\" \"\"              == \"x\"" $ replace "" "x" ""              == "x"
+    testGen "\\xs ys -> replace xs xs ys == ys" $ \xs ys -> replace xs xs ys == ys
     testGen "breakEnd isLower \"youRE\" == (\"you\",\"RE\")" $ breakEnd isLower "youRE" == ("you","RE")
     testGen "breakEnd isLower \"youre\" == (\"youre\",\"\")" $ breakEnd isLower "youre" == ("youre","")
     testGen "breakEnd isLower \"YOURE\" == (\"\",\"YOURE\")" $ breakEnd isLower "YOURE" == ("","YOURE")
@@ -271,6 +272,8 @@
     testGen "\\(xs :: [Int]) (ys :: [Int]) -> comparingLength xs ys == Data.Ord.comparing length xs ys" $ \(xs :: [Int]) (ys :: [Int]) -> comparingLength xs ys == Data.Ord.comparing length xs ys
     testGen "comparingLength [1,2] (1:2:3:undefined) == LT" $ comparingLength [1,2] (1:2:3:undefined) == LT
     testGen "comparingLength (1:2:3:undefined) [1,2] == GT" $ comparingLength (1:2:3:undefined) [1,2] == GT
+    testGen "mwhen True  \"test\" == \"test\"" $ mwhen True  "test" == "test"
+    testGen "mwhen False \"test\" == \"\"" $ mwhen False "test" == ""
     testGen "first succ (1,\"test\") == (2,\"test\")" $ first succ (1,"test") == (2,"test")
     testGen "second reverse (1,\"test\") == (1,\"tset\")" $ second reverse (1,"test") == (1,"tset")
     testGen "firstM (\\x -> [x-1, x+1]) (1,\"test\") == [(0,\"test\"),(2,\"test\")]" $ firstM (\x -> [x-1, x+1]) (1,"test") == [(0,"test"),(2,"test")]
diff --git a/test/TestUtil.hs b/test/TestUtil.hs
--- a/test/TestUtil.hs
+++ b/test/TestUtil.hs
@@ -24,7 +24,7 @@
 import Data.List.Extra as X hiding (union, unionBy)
 import Data.List.NonEmpty.Extra as X (NonEmpty(..), (|>), (|:), appendl, appendr, union, unionBy)
 import Data.Maybe as X
-import Data.Monoid as X
+import Data.Monoid.Extra as X
 import Data.Tuple.Extra as X
 import Data.Version.Extra as X
 import Numeric.Extra as X
