diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# 0.1.3.1
+
+- Revised the inlining of functions exported by `Data.MonoidMap`, so that GHC
+  can specialise them at call sites.
+
+- Revised version bounds for dependencies.
+
 # 0.1.3.0
 
 - Added a manual flag `nothunks`, which is on by default. Switching this flag
diff --git a/components/monoidmap/Data/MonoidMap.hs b/components/monoidmap/Data/MonoidMap.hs
--- a/components/monoidmap/Data/MonoidMap.hs
+++ b/components/monoidmap/Data/MonoidMap.hs
@@ -172,6 +172,8 @@
     ( NonNull )
 import Data.MonoidMap.Internal.NonNullMap
     ( NonNullMap (..) )
+import Data.MonoidMap.Internal.NonNullMap.Merge
+    ( Strategy (withNonNullL, withNonNullR, withNonNullP) )
 
 import Control.Applicative
     ( Applicative (..) )
@@ -201,7 +203,7 @@
 import Data.Map.Strict
     ( Map, lookup )
 import Data.Maybe
-    ( fromMaybe, isJust )
+    ( fromJust, isJust )
 import Data.Monoid.GCD
     ( DistributiveGCDMonoid
     , GCDMonoid
@@ -244,13 +246,13 @@
 import qualified Data.Group as C
 import qualified Data.List as L
 import qualified Data.List.NonEmpty as NE
-import qualified Data.Map.Merge.Strict as Map
 import qualified Data.Map.Strict as Map
 import qualified Data.Monoid.GCD as C
 import qualified Data.Monoid.LCM as C
 import qualified Data.Monoid.Null as C
 import qualified Data.MonoidMap.Internal.NonNull as NonNull
 import qualified Data.MonoidMap.Internal.NonNullMap as NonNullMap
+import qualified Data.MonoidMap.Internal.NonNullMap.Merge as Merge
 import qualified Data.Semigroup.Cancellative as C
 import qualified Data.Set as Set
 import qualified Data.Traversable as Traversable
@@ -601,13 +603,16 @@
   where
     type Item (MonoidMap k v) = (k, v)
     fromList = fromList
+    {-# INLINE fromList #-}
     toList = toList
+    {-# INLINE toList #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, Read k, MonoidNull v, Read v) =>
     Read (MonoidMap k v)
   where
     readPrec = fromMap <$> readPrec
+    {-# INLINE readPrec #-}
 
 --------------------------------------------------------------------------------
 -- Instances: Data
@@ -619,12 +624,17 @@
 -- | @since 0.0.5.0
 instance (Data k, Data v, Ord k, MonoidNull v) => Data (MonoidMap k v) where
     dataTypeOf _ = dataType
+    {-# INLINE dataTypeOf #-}
     dataCast2 f = gcast2 f
+    {-# INLINE dataCast2 #-}
     gfoldl f z m = z fromList `f` toList m
+    {-# INLINE gfoldl #-}
     gunfold k z c
         | c == fromListConstr = k (z fromList)
         | otherwise = error "gunfold MonoidMap: unexpected constructor"
+    {-# INLINE gunfold #-}
     toConstr _ = fromListConstr
+    {-# INLINE toConstr #-}
 
 dataType :: DataType
 dataType = mkDataType "Data.MonoidMap.MonoidMap" [fromListConstr]
@@ -640,7 +650,9 @@
 -- | @since 0.0.0.0
 instance (NoThunks k, NoThunks v) => NoThunks (MonoidMap k v) where
     showTypeOf _ = "MonoidMap"
+    {-# INLINE showTypeOf #-}
     wNoThunks ctx = wNoThunks ctx . toMap
+    {-# INLINE wNoThunks #-}
 #endif
 
 --------------------------------------------------------------------------------
@@ -652,9 +664,11 @@
     Semigroup (MonoidMap k v)
   where
     (<>) = append
+    {-# INLINE (<>) #-}
     stimes 0 = const mempty
     stimes 1 = id
     stimes n = map (stimes n)
+    {-# INLINE stimes #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, Commutative v) =>
@@ -665,20 +679,25 @@
     LeftReductive (MonoidMap k v)
   where
     isPrefixOf = isPrefixOf
+    {-# INLINE isPrefixOf #-}
     stripPrefix = stripPrefix
+    {-# INLINE stripPrefix #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, RightReductive v) =>
     RightReductive (MonoidMap k v)
   where
     isSuffixOf = isSuffixOf
+    {-# INLINE isSuffixOf #-}
     stripSuffix = stripSuffix
+    {-# INLINE stripSuffix #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, Reductive v) =>
     Reductive (MonoidMap k v)
   where
     (</>) = minusMaybe
+    {-# INLINE (</>) #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, LeftCancellative v) =>
@@ -701,12 +720,14 @@
     Monoid (MonoidMap k v)
   where
     mempty = empty
+    {-# INLINE mempty #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v) =>
     MonoidNull (MonoidMap k v)
   where
     null = null
+    {-# INLINE null #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, PositiveMonoid v) =>
@@ -717,6 +738,9 @@
     LeftGCDMonoid (MonoidMap k v)
   where
     commonPrefix = commonPrefix
+    {-# INLINE commonPrefix #-}
+    stripCommonPrefix = stripCommonPrefix
+    {-# INLINE stripCommonPrefix #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, LeftDistributiveGCDMonoid v) =>
@@ -727,6 +751,9 @@
     RightGCDMonoid (MonoidMap k v)
   where
     commonSuffix = commonSuffix
+    {-# INLINE commonSuffix #-}
+    stripCommonSuffix = stripCommonSuffix
+    {-# INLINE stripCommonSuffix #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, RightDistributiveGCDMonoid v) =>
@@ -737,15 +764,20 @@
     OverlappingGCDMonoid (MonoidMap k v)
   where
     overlap = overlap
+    {-# INLINE overlap #-}
     stripPrefixOverlap = stripPrefixOverlap
+    {-# INLINE stripPrefixOverlap #-}
     stripSuffixOverlap = stripSuffixOverlap
+    {-# INLINE stripSuffixOverlap #-}
     stripOverlap = stripOverlap
+    {-# INLINE stripOverlap #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, GCDMonoid v) =>
     GCDMonoid (MonoidMap k v)
   where
     gcd = intersection
+    {-# INLINE gcd #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, DistributiveGCDMonoid v) =>
@@ -756,6 +788,7 @@
     LCMMonoid (MonoidMap k v)
   where
     lcm = union
+    {-# INLINE lcm #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, DistributiveLCMMonoid v) =>
@@ -766,6 +799,7 @@
     Monus (MonoidMap k v)
   where
     (<\>) = monus
+    {-# INLINE (<\>) #-}
 
 --------------------------------------------------------------------------------
 -- Instances: Group and subclasses
@@ -776,8 +810,11 @@
     Group (MonoidMap k v)
   where
     invert = invert
+    {-# INLINE invert #-}
     (~~) = minus
+    {-# INLINE (~~) #-}
     pow = power
+    {-# INLINE pow #-}
 
 -- | @since 0.0.0.0
 instance (Ord k, MonoidNull v, Abelian v) =>
@@ -802,6 +839,7 @@
 --
 empty :: MonoidMap k v
 empty = MonoidMap Map.empty
+{-# INLINE empty #-}
 
 -- | \(O(n \log n)\). Constructs a 'MonoidMap' from a list of key-value pairs.
 --
@@ -834,6 +872,7 @@
 --
 fromList :: (Ord k, MonoidNull v) => [(k, v)] -> MonoidMap k v
 fromList = fromListWith (<>)
+{-# INLINE fromList #-}
 
 -- | \(O(n \log n)\). Constructs a 'MonoidMap' from a list of key-value pairs,
 --   with a combining function for values.
@@ -862,6 +901,7 @@
     -- The 'Map.fromListWith' function combines values for duplicate keys in
     -- /reverse order/, so we must flip the provided combining function.
     fromMap . Map.fromListWith (flip f)
+{-# INLINE fromListWith #-}
 
 -- | \(O(n)\). Constructs a 'MonoidMap' from an ordinary 'Map'.
 --
@@ -878,7 +918,7 @@
 --
 fromMap :: MonoidNull v => Map k v -> MonoidMap k v
 fromMap = fromNonNullMap . NonNullMap.fromMap
-{-# INLINABLE fromMap #-}
+{-# INLINE fromMap #-}
 
 -- | \(O(n)\). Constructs a 'MonoidMap' from an ordinary 'Map', applying
 --   the given function to all values.
@@ -896,7 +936,7 @@
 --
 fromMapWith :: MonoidNull v2 => (v1 -> v2) -> Map k v1 -> MonoidMap k v2
 fromMapWith f = fromNonNullMap . NonNullMap.fromMapWith f
-{-# INLINABLE fromMapWith #-}
+{-# INLINE fromMapWith #-}
 
 -- | \(O(n)\). Constructs a 'MonoidMap' from a 'Set' and a function from
 --   keys to values.
@@ -917,6 +957,7 @@
 --
 fromSet :: MonoidNull v => (k -> v) -> Set k -> MonoidMap k v
 fromSet f = fromMap . Map.fromSet f
+{-# INLINE fromSet #-}
 
 -- | \(O(1)\). Constructs a 'MonoidMap' from a single key-value pair.
 --
@@ -936,6 +977,7 @@
 --
 singleton :: (Ord k, MonoidNull v) => k -> v -> MonoidMap k v
 singleton k v = set k v mempty
+{-# INLINE singleton #-}
 
 --------------------------------------------------------------------------------
 -- Deconstruction
@@ -962,6 +1004,7 @@
 --
 toList :: MonoidMap k v -> [(k, v)]
 toList = Map.toAscList . toMap
+{-# INLINE toList #-}
 
 -- | \(O(1)\). Converts a 'MonoidMap' to an ordinary 'Map'.
 --
@@ -995,7 +1038,8 @@
 -- @since 0.0.0.0
 --
 get :: (Ord k, Monoid v) => k -> MonoidMap k v -> v
-get k m = fromMaybe mempty $ Map.lookup k $ toMap m
+get k = NonNullMap.get k . toNonNullMap
+{-# INLINE get #-}
 
 --------------------------------------------------------------------------------
 -- Modification
@@ -1015,6 +1059,7 @@
 set k v (MonoidMap m) = MonoidMap $ case NonNull.nonNull v of
     Just v0 -> Map.insert k v0 m
     Nothing -> Map.delete k    m
+{-# INLINE set #-}
 
 -- | \(O(\log n)\). Adjusts the value associated with the given key.
 --
@@ -1034,6 +1079,7 @@
     -> MonoidMap k v
 adjust f k (MonoidMap m) = MonoidMap $
     Map.alter (NonNull.nonNull . maybe (f mempty) (NonNull.apply f)) k m
+{-# INLINE adjust #-}
 
 --------------------------------------------------------------------------------
 -- Nullification
@@ -1054,6 +1100,7 @@
 --
 nullify :: Ord k => k -> MonoidMap k v -> MonoidMap k v
 nullify k (MonoidMap m) = MonoidMap $ Map.delete k m
+{-# INLINE nullify #-}
 
 -- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
 --
@@ -1077,6 +1124,7 @@
 --
 nullifyKeysIn :: Ord k => Set k -> MonoidMap k v -> MonoidMap k v
 nullifyKeysIn ks (MonoidMap m) = MonoidMap $ m `Map.withoutKeys` ks
+{-# INLINE nullifyKeysIn #-}
 
 -- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
 --
@@ -1100,6 +1148,7 @@
 --
 nullifyKeysNotIn :: Ord k => Set k -> MonoidMap k v -> MonoidMap k v
 nullifyKeysNotIn ks (MonoidMap m) = MonoidMap $ m `Map.restrictKeys` ks
+{-# INLINE nullifyKeysNotIn #-}
 
 --------------------------------------------------------------------------------
 -- Membership
@@ -1121,6 +1170,7 @@
 --
 null :: MonoidMap k v -> Bool
 null = Map.null . toMap
+{-# INLINE null #-}
 
 -- | \(O(\log n)\). Returns 'True' if (and only if) the given key is associated
 --   with a value that is 'C.null'.
@@ -1135,6 +1185,7 @@
 --
 nullKey :: Ord k => k -> MonoidMap k v -> Bool
 nullKey k = Map.notMember k . toMap
+{-# INLINE nullKey #-}
 
 -- | \(O(1)\). Returns 'True' if (and only if) the map contains at least one
 --   value that is not 'C.null'.
@@ -1149,6 +1200,7 @@
 --
 nonNull :: MonoidMap k v -> Bool
 nonNull = not . null
+{-# INLINE nonNull #-}
 
 -- | \(O(1)\). Returns a count of all values in the map that are not 'C.null'.
 --
@@ -1162,6 +1214,7 @@
 --
 nonNullCount :: MonoidMap k v -> Int
 nonNullCount = Map.size . toMap
+{-# INLINE nonNullCount #-}
 
 -- | \(O(\log n)\). Returns 'True' if (and only if) the given key is associated
 --   with a value that is not 'C.null'.
@@ -1176,6 +1229,7 @@
 --
 nonNullKey :: Ord k => k -> MonoidMap k v -> Bool
 nonNullKey k = Map.member k . toMap
+{-# INLINE nonNullKey #-}
 
 -- | \(O(n)\). Returns the set of keys associated with values that are not
 --   'C.null'.
@@ -1190,6 +1244,7 @@
 --
 nonNullKeys :: MonoidMap k v -> Set k
 nonNullKeys = Map.keysSet . toMap
+{-# INLINE nonNullKeys #-}
 
 --------------------------------------------------------------------------------
 -- Slicing
@@ -1212,6 +1267,7 @@
 --
 take :: Int -> MonoidMap k v -> MonoidMap k v
 take i (MonoidMap m) = MonoidMap (Map.take i m)
+{-# INLINE take #-}
 
 -- | \(O(\log n)\). /Drops/ a slice from a map.
 --
@@ -1230,6 +1286,7 @@
 --
 drop :: Int -> MonoidMap k v -> MonoidMap k v
 drop i (MonoidMap m) = MonoidMap (Map.drop i m)
+{-# INLINE drop #-}
 
 -- | \(O(\log n)\). /Splits/ a map into /two/ slices.
 --
@@ -1257,6 +1314,7 @@
 --
 splitAt :: Int -> MonoidMap k a -> (MonoidMap k a, MonoidMap k a)
 splitAt i m = (take i m, drop i m)
+{-# INLINE splitAt #-}
 
 --------------------------------------------------------------------------------
 -- Filtering
@@ -1284,6 +1342,7 @@
 --
 filter :: (v -> Bool) -> MonoidMap k v -> MonoidMap k v
 filter f (MonoidMap m) = MonoidMap $ Map.filter (NonNull.apply f) m
+{-# INLINE filter #-}
 
 -- | \(O(n)\). Filters a map according to a predicate on /keys/.
 --
@@ -1307,6 +1366,7 @@
 --
 filterKeys :: (k -> Bool) -> MonoidMap k v -> MonoidMap k v
 filterKeys f (MonoidMap m) = MonoidMap $ Map.filterWithKey (\k _ -> f k) m
+{-# INLINE filterKeys #-}
 
 -- | \(O(n)\). Filters a map according to a predicate on /keys and values/.
 --
@@ -1331,6 +1391,7 @@
 filterWithKey :: (k -> v -> Bool) -> MonoidMap k v -> MonoidMap k v
 filterWithKey f (MonoidMap m) =
     MonoidMap $ Map.filterWithKey (NonNull.apply . f) m
+{-# INLINE filterWithKey #-}
 
 --------------------------------------------------------------------------------
 -- Partitioning
@@ -1368,6 +1429,7 @@
 partition :: (v -> Bool) -> MonoidMap k v -> (MonoidMap k v, MonoidMap k v)
 partition f (MonoidMap m) =
     B.bimap MonoidMap MonoidMap $ Map.partition (NonNull.apply f) m
+{-# INLINE partition #-}
 
 -- | \(O(n)\). Partitions a map according to a predicate on /keys/.
 --
@@ -1402,6 +1464,7 @@
     :: (k -> Bool) -> MonoidMap k v -> (MonoidMap k v, MonoidMap k v)
 partitionKeys f (MonoidMap m) =
     B.bimap MonoidMap MonoidMap $ Map.partitionWithKey (\k _ -> f k) m
+{-# INLINE partitionKeys #-}
 
 -- | \(O(n)\). Partitions a map according to a predicate on /keys and values/.
 --
@@ -1436,6 +1499,7 @@
     :: (k -> v -> Bool) -> MonoidMap k v -> (MonoidMap k v, MonoidMap k v)
 partitionWithKey f (MonoidMap m) =
     B.bimap MonoidMap MonoidMap $ Map.partitionWithKey (NonNull.apply . f) m
+{-# INLINE partitionWithKey #-}
 
 --------------------------------------------------------------------------------
 -- Mapping
@@ -1476,6 +1540,7 @@
     -> MonoidMap k v2
 map f (MonoidMap m) =
     MonoidMap $ Map.mapMaybe (NonNull.nonNull . NonNull.apply f) m
+{-# INLINE map #-}
 
 -- | \(O(n \log n)\). Applies a function to all the keys of a 'MonoidMap' that
 --   are associated with non-'C.null' values.
@@ -1501,6 +1566,7 @@
     -> MonoidMap k1 v
     -> MonoidMap k2 v
 mapKeys = mapKeysWith (<>)
+{-# INLINE mapKeys #-}
 
 -- | \(O(n \log n)\). Applies a function to all the keys of a 'MonoidMap' that
 --   are associated with non-'C.null' values, with a combining function for
@@ -1526,6 +1592,7 @@
     -> MonoidMap k1 v
     -> MonoidMap k2 v
 mapKeysWith combine fk = fromListWith combine . fmap (B.first fk) . toList
+{-# INLINE mapKeysWith #-}
 
 -- | \(O(n)\). Applies a key-dependent function to all non-'C.null' values of
 --   a 'MonoidMap'.
@@ -1548,6 +1615,7 @@
     MonoidMap . runIdentity $
     Map.traverseMaybeWithKey
         (\k v -> Identity $ NonNull.nonNull $ NonNull.apply (f k) v) m
+{-# INLINE mapWithKey #-}
 
 --------------------------------------------------------------------------------
 -- Folding
@@ -2038,21 +2106,21 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-append = merge MergeStrategy
+append = merge Merge.Strategy
     { withNonNullL =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- v <> mempty ≡ v
 
     , withNonNullR =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- mempty <> v ≡ v
 
     , withNonNullP =
-        withBoth (<>)
+        Merge.withBoth (<>)
     }
 {-# INLINE append #-}
 
@@ -2370,18 +2438,18 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> Maybe (MonoidMap k v)
-stripPrefix = mergeA MergeStrategy
+stripPrefix = mergeA Merge.Strategy
     { withNonNullL =
-        withNonNullA (\v -> C.stripPrefix v mempty)
+        Merge.withNonNullA (\v -> C.stripPrefix v mempty)
 
     , withNonNullR =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- stripPrefix mempty a ≡ a
 
     , withNonNullP =
-        withBothA C.stripPrefix
+        Merge.withBothA C.stripPrefix
     }
 {-# INLINE stripPrefix #-}
 
@@ -2463,18 +2531,18 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> Maybe (MonoidMap k v)
-stripSuffix = mergeA MergeStrategy
+stripSuffix = mergeA Merge.Strategy
     { withNonNullL =
-        withNonNullA (\v -> C.stripSuffix v mempty)
+        Merge.withNonNullA (\v -> C.stripSuffix v mempty)
 
     , withNonNullR =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- stripSuffix mempty a ≡ a
 
     , withNonNullP =
-        withBothA C.stripSuffix
+        Merge.withBothA C.stripSuffix
     }
 {-# INLINE stripSuffix #-}
 
@@ -2523,21 +2591,21 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-commonPrefix = merge MergeStrategy
+commonPrefix = merge Merge.Strategy
     { withNonNullL =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- commonPrefix a mempty ≡ mempty
 
     , withNonNullR =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- commonPrefix mempty a ≡ mempty
 
     , withNonNullP =
-        withBoth C.commonPrefix
+        Merge.withBoth C.commonPrefix
     }
 {-# INLINE commonPrefix #-}
 
@@ -2586,21 +2654,21 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-commonSuffix = merge MergeStrategy
+commonSuffix = merge Merge.Strategy
     { withNonNullL =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- commonSuffix a mempty ≡ mempty
 
     , withNonNullR =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- commonSuffix mempty a ≡ mempty
 
     , withNonNullP =
-        withBoth C.commonSuffix
+        Merge.withBoth C.commonSuffix
     }
 {-# INLINE commonSuffix #-}
 
@@ -2687,7 +2755,29 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> (MonoidMap k v, MonoidMap k v, MonoidMap k v)
-stripCommonPrefix = C.stripCommonPrefix
+stripCommonPrefix m1 m2 =
+    --
+    -- This implementation is equivalent to the default implementation of
+    -- 'stripCommonPrefix' in 'LeftGCDMonoid'.
+    --
+    -- As @p@ is a prefix of both maps, stripping @p@ from either map cannot
+    -- fail.
+    --
+    -- However, this approach has two drawbacks: firstly, it uses 'fromJust',
+    -- which is a partial function; and secondly, it is inefficient, as for
+    -- each key, 'stripPrefix' must repeat the comparison of values already
+    -- performed by 'commonPrefix'.
+    --
+    -- Applying 'C.stripCommonPrefix' pointwise to each pair of values just
+    -- once could avoid both problems.
+    --
+    ( p
+    , fromJust (stripPrefix p m1)
+    , fromJust (stripPrefix p m2)
+    )
+  where
+    p = commonPrefix m1 m2
+{-# INLINE stripCommonPrefix #-}
 
 -- | Strips the /greatest common suffix/ from a pair of maps.
 --
@@ -2772,7 +2862,29 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> (MonoidMap k v, MonoidMap k v, MonoidMap k v)
-stripCommonSuffix = C.stripCommonSuffix
+stripCommonSuffix m1 m2 =
+    --
+    -- This implementation is equivalent to the default implementation of
+    -- 'stripCommonSuffix' in 'RightGCDMonoid'.
+    --
+    -- As @s@ is a suffix of both maps, stripping @s@ from either map cannot
+    -- fail.
+    --
+    -- However, this approach has two drawbacks: firstly, it uses 'fromJust',
+    -- which is a partial function; and secondly, it is inefficient, as for
+    -- each key, 'stripSuffix' must repeat the comparison of values already
+    -- performed by 'commonSuffix'.
+    --
+    -- Applying 'C.stripCommonSuffix' pointwise to each pair of values just
+    -- once could avoid both problems.
+    --
+    ( fromJust (stripSuffix s m1)
+    , fromJust (stripSuffix s m2)
+    , s
+    )
+  where
+    s = commonSuffix m1 m2
+{-# INLINE stripCommonSuffix #-}
 
 --------------------------------------------------------------------------------
 -- Overlap
@@ -2842,21 +2954,21 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-overlap = merge MergeStrategy
+overlap = merge Merge.Strategy
     { withNonNullL =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- overlap a mempty ≡ mempty
 
     , withNonNullR =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- overlap mempty a ≡ mempty
 
     , withNonNullP =
-        withBoth C.overlap
+        Merge.withBoth C.overlap
     }
 {-# INLINE overlap #-}
 
@@ -2918,9 +3030,9 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-stripPrefixOverlap = merge MergeStrategy
+stripPrefixOverlap = merge Merge.Strategy
     { withNonNullL =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- overlap a b      <> stripPrefixOverlap a b      ≡ b
@@ -2929,7 +3041,7 @@
         --                     stripPrefixOverlap a mempty ≡ mempty
 
     , withNonNullR =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- overlap a      b <> stripPrefixOverlap a      b ≡ b
@@ -2938,7 +3050,7 @@
         --                     stripPrefixOverlap mempty b ≡ b
 
     , withNonNullP =
-        withBoth C.stripPrefixOverlap
+        Merge.withBoth C.stripPrefixOverlap
     }
 {-# INLINE stripPrefixOverlap #-}
 
@@ -3000,9 +3112,9 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-stripSuffixOverlap = merge MergeStrategy
+stripSuffixOverlap = merge Merge.Strategy
     { withNonNullL =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- stripSuffixOverlap b a      <> overlap a      b ≡ a
@@ -3011,7 +3123,7 @@
         -- stripSuffixOverlap b mempty                     ≡ mempty
 
     , withNonNullR =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- stripSuffixOverlap b      a <> overlap a b      ≡ a
@@ -3020,7 +3132,7 @@
         -- stripSuffixOverlap mempty a                     ≡ a
 
     , withNonNullP =
-        withBoth C.stripSuffixOverlap
+        Merge.withBoth C.stripSuffixOverlap
     }
 {-# INLINE stripSuffixOverlap #-}
 
@@ -3077,6 +3189,7 @@
     , m1 `overlap` m2
     , stripPrefixOverlap m1 m2
     )
+{-# INLINE stripOverlap #-}
 
 --------------------------------------------------------------------------------
 -- Intersection
@@ -3165,21 +3278,21 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-intersection = merge MergeStrategy
+intersection = merge Merge.Strategy
     { withNonNullL =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- gcd a mempty ≡ mempty
 
     , withNonNullR =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- gcd mempty b ≡ mempty
 
     , withNonNullP =
-        withBoth C.gcd
+        Merge.withBoth C.gcd
     }
 {-# INLINE intersection #-}
 
@@ -3270,21 +3383,21 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-union = merge MergeStrategy
+union = merge Merge.Strategy
     { withNonNullL =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- lcm a mempty ≡ a
 
     , withNonNullR =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- lcm mempty a ≡ a
 
     , withNonNullP =
-        withBoth C.lcm
+        Merge.withBoth C.lcm
     }
 {-# INLINE union #-}
 
@@ -3338,15 +3451,15 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-minus = merge MergeStrategy
+minus = merge Merge.Strategy
     { withNonNullL =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- a ~~ mempty ≡ a
 
     , withNonNullR =
-        withNonNull C.invert
+        Merge.withNonNull C.invert
         -- Justification:
         --
         -- a      ~~ b ≡ a      <> invert b
@@ -3354,7 +3467,7 @@
         -- mempty ~~ b ≡           invert b
 
     , withNonNullP =
-        withBoth (C.~~)
+        Merge.withBoth (C.~~)
     }
 {-# INLINE minus #-}
 
@@ -3474,9 +3587,9 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> Maybe (MonoidMap k v)
-minusMaybe = mergeA MergeStrategy
+minusMaybe = mergeA Merge.Strategy
     { withNonNullL =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- According to laws for Reductive:
@@ -3498,10 +3611,10 @@
         -- a </> mempty ≡ Just a
 
     , withNonNullR =
-        withNonNullA (\v -> mempty </> v)
+        Merge.withNonNullA (\v -> mempty </> v)
 
     , withNonNullP =
-        withBothA (</>)
+        Merge.withBothA (</>)
     }
 {-# INLINE minusMaybe #-}
 
@@ -3608,9 +3721,9 @@
     => MonoidMap k v
     -> MonoidMap k v
     -> MonoidMap k v
-monus = merge MergeStrategy
+monus = merge Merge.Strategy
     { withNonNullL =
-        keepNonNull
+        Merge.keepNonNull
         -- Justification:
         --
         -- a      <> (b <\> a     ) ≡ b <> (a      <\> b)
@@ -3620,13 +3733,13 @@
         --            b <\> mempty  ≡ b
 
     , withNonNullR =
-        keepNull
+        Merge.keepNull
         -- Justification:
         --
         -- mempty <\> a ≡ mempty
 
     , withNonNullP =
-        withBoth (<\>)
+        Merge.withBoth (<\>)
     }
 {-# INLINE monus #-}
 
@@ -3778,13 +3891,13 @@
     -> MonoidMap k v1
     -> MonoidMap k v2
     -> MonoidMap k v3
-intersectionWith f = merge MergeStrategy
+intersectionWith f = merge Merge.Strategy
     { withNonNullL =
-        keepNull
+        Merge.keepNull
     , withNonNullR =
-        keepNull
+        Merge.keepNull
     , withNonNullP =
-        withBoth f
+        Merge.withBoth f
     }
 {-# INLINE intersectionWith #-}
 
@@ -3806,13 +3919,13 @@
     -> MonoidMap k v1
     -> MonoidMap k v2
     -> f (MonoidMap k v3)
-intersectionWithA f = mergeA MergeStrategy
+intersectionWithA f = mergeA Merge.Strategy
     { withNonNullL =
-        keepNull
+        Merge.keepNull
     , withNonNullR =
-        keepNull
+        Merge.keepNull
     , withNonNullP =
-        withBothA f
+        Merge.withBothA f
     }
 {-# INLINE intersectionWithA #-}
 
@@ -3873,13 +3986,13 @@
     -> MonoidMap k v1
     -> MonoidMap k v2
     -> MonoidMap k v3
-unionWith f = merge MergeStrategy
+unionWith f = merge Merge.Strategy
     { withNonNullL =
-        withNonNull (\v -> f v mempty)
+        Merge.withNonNull (\v -> f v mempty)
     , withNonNullR =
-        withNonNull (\v -> f mempty v)
+        Merge.withNonNull (\v -> f mempty v)
     , withNonNullP =
-        withBoth f
+        Merge.withBoth f
     }
 {-# INLINE unionWith #-}
 
@@ -3901,13 +4014,13 @@
     -> MonoidMap k v1
     -> MonoidMap k v2
     -> f (MonoidMap k v3)
-unionWithA f = mergeA MergeStrategy
+unionWithA f = mergeA Merge.Strategy
     { withNonNullL =
-        withNonNullA (\v -> f v mempty)
+        Merge.withNonNullA (\v -> f v mempty)
     , withNonNullR =
-        withNonNullA (\v -> f mempty v)
+        Merge.withNonNullA (\v -> f mempty v)
     , withNonNullP =
-        withBothA f
+        Merge.withBothA f
     }
 {-# INLINE unionWithA #-}
 
@@ -3915,84 +4028,25 @@
 -- Merging
 --------------------------------------------------------------------------------
 
-type WhenOneSideNull f k          vx                        vr
-   = Map.WhenMissing f k (NonNull vx)              (NonNull vr)
-type WhenBothNonNull f k          v1           v2           vr
-   = Map.WhenMatched f k (NonNull v1) (NonNull v2) (NonNull vr)
-
-data MergeStrategy f k v1 v2 v3 = MergeStrategy
-    { withNonNullL :: !(WhenOneSideNull f k v1    v3)
-    , withNonNullR :: !(WhenOneSideNull f k    v2 v3)
-    , withNonNullP :: !(WhenBothNonNull f k v1 v2 v3)
-    }
-
 merge
     :: Ord k
-    => MergeStrategy Identity k v1 v2 v3
+    => Merge.Strategy Identity k v1 v2 v3
     -> MonoidMap k v1
     -> MonoidMap k v2
     -> MonoidMap k v3
-merge (MergeStrategy nnl nnr nnp) (MonoidMap m1) (MonoidMap m2) =
-    MonoidMap $ Map.merge nnl nnr nnp m1 m2
+merge s m1 m2 =
+    fromNonNullMap $ Merge.merge s (toNonNullMap m1) (toNonNullMap m2)
 {-# INLINE merge #-}
 
 mergeA
     :: (Applicative f, Ord k)
-    => MergeStrategy f k v1 v2 v3
+    => Merge.Strategy f k v1 v2 v3
     -> MonoidMap k v1
     -> MonoidMap k v2
     -> f (MonoidMap k v3)
-mergeA (MergeStrategy nnl nnr nnp) (MonoidMap m1) (MonoidMap m2) =
-    MonoidMap <$> Map.mergeA nnl nnr nnp m1 m2
+mergeA s m1 m2 =
+    fromNonNullMap <$> Merge.mergeA s (toNonNullMap m1) (toNonNullMap m2)
 {-# INLINE mergeA #-}
-
-keepNull
-    :: Applicative f
-    => WhenOneSideNull f k v1 v2
-keepNull = Map.dropMissing
-{-# INLINE keepNull #-}
-
-keepNonNull
-    :: Applicative f
-    => WhenOneSideNull f k v v
-keepNonNull = Map.preserveMissing
-{-# INLINE keepNonNull #-}
-
-withNonNull
-    :: (Applicative f, MonoidNull v2)
-    => (v1 -> v2)
-    -> WhenOneSideNull f k v1 v2
-withNonNull f
-    = Map.mapMaybeMissing
-    $ \_k v -> NonNull.nonNull $ NonNull.apply f v
-{-# INLINE withNonNull #-}
-
-withNonNullA
-    :: (Applicative f, MonoidNull v2)
-    => (v1 -> f v2)
-    -> WhenOneSideNull f k v1 v2
-withNonNullA f
-    = Map.traverseMaybeMissing
-    $ \_k v -> NonNull.nonNull <$> NonNull.apply f v
-{-# INLINE withNonNullA #-}
-
-withBoth
-    :: (Applicative f, MonoidNull v3)
-    => (v1 -> v2 -> v3)
-    -> WhenBothNonNull f k v1 v2 v3
-withBoth f
-    = Map.zipWithMaybeMatched
-    $ \_k v1 v2 -> NonNull.nonNull $ NonNull.apply2 f v1 v2
-{-# INLINE withBoth #-}
-
-withBothA
-    :: (Applicative f, MonoidNull v3)
-    => (v1 -> v2 -> f v3)
-    -> WhenBothNonNull f k v1 v2 v3
-withBothA f
-    = Map.zipWithMaybeAMatched
-    $ \_k v1 v2 -> NonNull.nonNull <$> NonNull.apply2 f v1 v2
-{-# INLINE withBothA #-}
 
 --------------------------------------------------------------------------------
 -- State
diff --git a/monoidmap.cabal b/monoidmap.cabal
--- a/monoidmap.cabal
+++ b/monoidmap.cabal
@@ -1,6 +1,6 @@
 cabal-version:  3.0
 name:           monoidmap
-version:        0.1.3.0
+version:        0.1.3.1
 homepage:       https://github.com/jonathanknowles/monoidmap
 bug-reports:    https://github.com/jonathanknowles/monoidmap/issues
 license:        Apache-2.0
@@ -40,7 +40,7 @@
 common dependency-monoid-subclasses
     build-depends:monoid-subclasses             >= 1.2.3      && < 1.3
 common dependency-monoidmap-internal
-    build-depends:monoidmap-internal            >= 0.5.0.0    && < 0.6
+    build-depends:monoidmap-internal            >= 0.5.1.0    && < 0.6
 common dependency-nothunks
     if flag(nothunks)
         build-depends:nothunks                  >= 0.1.3      && < 0.4
