diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+Version 1.2
+---------------
+* Depending on new `commutative-semigroups` package
+* Modified the `instance OverlappingMonoid/Monus Map/IntMap` instances to conform with the class laws
+* Bumped the `vector` dependency upper bounds
+
+Version 1.1.4
+---------------
+* Canonicalized all `mappend` definitions
+* Added `deriving (Data, Typeable)` to all data types
+
 Version 1.1.3
 ---------------
 * Support for text-2.0 by Bodigrim
diff --git a/Test/TestMonoidSubclasses.hs b/Test/TestMonoidSubclasses.hs
--- a/Test/TestMonoidSubclasses.hs
+++ b/Test/TestMonoidSubclasses.hs
@@ -73,7 +73,8 @@
 import Data.Monoid.GCD (GCDMonoid, LeftGCDMonoid, RightGCDMonoid, gcd,
                         commonPrefix, stripCommonPrefix,
                         commonSuffix, stripCommonSuffix)
-import Data.Monoid.Monus (OverlappingGCDMonoid, Monus, (<\>), stripPrefixOverlap, stripSuffixOverlap)
+import Data.Monoid.Monus (OverlappingGCDMonoid, Monus,
+                          (<\>), overlap, stripOverlap, stripPrefixOverlap, stripSuffixOverlap)
 import Data.Monoid.Textual (TextualMonoid)
 import qualified Data.Monoid.Textual as Textual
 
@@ -456,6 +457,9 @@
          ("stripSuffixOverlap 1", OverlappingGCDTest checkStripSuffixOverlap1),
          ("stripSuffixOverlap 2", OverlappingGCDTest checkStripSuffixOverlap2),
          ("stripSuffixOverlap 3", OverlappingGCDTest checkStripSuffixOverlap3),
+         ("overlap law 1", OverlappingGCDTest checkOverlapLaw1),
+         ("overlap law 2", OverlappingGCDTest checkOverlapLaw2),
+         ("overlap law 3", OverlappingGCDTest checkOverlapLaw3),
          ("isPrefixOf", LeftReductiveTest checkIsPrefixOf),
          ("stripSuffix", RightReductiveTest checkStripSuffix),
          ("isSuffixOf", RightReductiveTest checkIsSuffixOf),
@@ -777,6 +781,15 @@
 checkUnAppend (ReductiveMonoidInstance (_ :: a)) = forAll (arbitrary :: Gen (a, a)) check
    where check (a, b) = maybe a (b <>) (a </> b) == a
                         && maybe a (<> b) (a </> b) == a
+
+checkOverlapLaw1 (OverlappingGCDMonoidInstance (_ :: a)) = forAll (arbitrary :: Gen (a, a)) check
+   where check (a, b) = stripOverlap a b == (stripSuffixOverlap b a, overlap a b, stripPrefixOverlap a b)
+
+checkOverlapLaw2 (OverlappingGCDMonoidInstance (_ :: a)) = forAll (arbitrary :: Gen (a, a)) check
+   where check (a, b) = stripSuffixOverlap b a <> overlap a b == a
+
+checkOverlapLaw3 (OverlappingGCDMonoidInstance (_ :: a)) = forAll (arbitrary :: Gen (a, a)) check
+   where check (a, b) = overlap a b <> stripPrefixOverlap a b == b
 
 checkStripPrefixOverlap1 (OverlappingGCDMonoidInstance (_ :: a)) = forAll (arbitrary :: Gen (a, a)) check
    where check (a, b) = o `isSuffixOf` b && b `isSuffixOf` (a <> o)
diff --git a/monoid-subclasses.cabal b/monoid-subclasses.cabal
--- a/monoid-subclasses.cabal
+++ b/monoid-subclasses.cabal
@@ -1,5 +1,5 @@
 Name:                monoid-subclasses
-Version:             1.1.3
+Version:             1.2
 Cabal-Version:       >= 1.10
 Build-Type:          Simple
 Synopsis:            Subclasses of Monoid
@@ -30,8 +30,12 @@
                      Data.Monoid.Instances.Concat, Data.Monoid.Instances.Measured, Data.Monoid.Instances.Positioned,
                      Data.Monoid.Instances.Stateful
   Build-Depends:     base >= 4.9 && < 5,
-                     bytestring >= 0.9 && < 1.0, containers >= 0.5.7.0 && < 0.7, text >= 0.11 && < 1.3 || >= 2.0 && < 2.1,
-                     primes == 0.2.*, vector >= 0.12 && < 0.13
+                     bytestring >= 0.9 && < 1.0,
+                     containers >= 0.5.7.0 && < 0.7,
+                     text >= 0.11 && < 1.3 || >= 2.0 && < 2.1,
+                     primes == 0.2.*,
+                     vector >= 0.12 && < 0.14,
+                     commutative-semigroups >= 0.1 && < 0.2
   GHC-options:       -Wall
   default-language:  Haskell2010
 
@@ -39,7 +43,7 @@
   Type:              exitcode-stdio-1.0
   Build-Depends:     base >= 4.9 && < 5,
                      bytestring >= 0.9 && < 1.0, containers >= 0.5.7.0 && < 0.7, text >= 0.11 && < 1.3 || >= 2.0 && < 2.1,
-                     vector >= 0.12 && < 0.13, primes == 0.2.*,
+                     vector >= 0.12 && < 0.14, primes == 0.2.*,
                      QuickCheck >= 2.9 && < 3, quickcheck-instances >= 0.3.12 && <0.4,
                      tasty >= 0.7, tasty-quickcheck >= 0.7 && < 1.0,
                      monoid-subclasses
diff --git a/src/Data/Monoid/Factorial.hs b/src/Data/Monoid/Factorial.hs
--- a/src/Data/Monoid/Factorial.hs
+++ b/src/Data/Monoid/Factorial.hs
@@ -143,6 +143,18 @@
    drop n p = snd (splitAt n p)
    take n p = fst (splitAt n p)
    {-# MINIMAL #-}
+   {-# INLINABLE splitPrimePrefix #-}
+   {-# INLINABLE splitPrimeSuffix #-}
+   {-# INLINABLE inits #-}
+   {-# INLINABLE tails #-}
+   {-# INLINABLE span #-}
+   {-# INLINE break #-}
+   {-# INLINABLE spanMaybe #-}
+   {-# INLINABLE spanMaybe' #-}
+   {-# INLINABLE split #-}
+   {-# INLINE takeWhile #-}
+   {-# INLINE dropWhile #-}
+   {-# INLINABLE splitAt #-}
 
 {-# DEPRECATED StableFactorialMonoid "Use Data.Semigroup.Factorial.StableFactorial instead." #-}
 type StableFactorialMonoid m = (StableFactorial m, FactorialMonoid m, PositiveMonoid m)
diff --git a/src/Data/Monoid/Instances/ByteString/UTF8.hs b/src/Data/Monoid/Instances/ByteString/UTF8.hs
--- a/src/Data/Monoid/Instances/ByteString/UTF8.hs
+++ b/src/Data/Monoid/Instances/ByteString/UTF8.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2013-2019 Mario Blazevic
+    Copyright 2013-2022 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -32,7 +32,7 @@
 -- >> factors utf8'
 -- >["D","<","l","b","\[193,177]"]
 
-{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE Haskell2010, DeriveDataTypeable #-}
 
 module Data.Monoid.Instances.ByteString.UTF8 (
    ByteStringUTF8(..), decode
@@ -42,6 +42,7 @@
 import Control.Exception (assert)
 import Data.Bits ((.&.), (.|.), shiftL, shiftR)
 import Data.Char (chr, ord, isDigit, isPrint)
+import Data.Data (Data, Typeable)
 import qualified Data.Foldable as Foldable
 import qualified Data.List as List
 import Data.Maybe (fromMaybe, isJust, isNothing)
@@ -69,7 +70,7 @@
 import Prelude hiding (any, drop, dropWhile, foldl, foldl1, foldr, foldr1, scanl, scanr, scanl1, scanr1,
                        map, concatMap, break, span)
 
-newtype ByteStringUTF8 = ByteStringUTF8 ByteString deriving (Eq, Ord)
+newtype ByteStringUTF8 = ByteStringUTF8 ByteString deriving (Data, Eq, Ord, Typeable)
 
 -- | Takes a raw 'ByteString' chunk and returns a pair of 'ByteStringUTF8' decoding the prefix of the chunk and the
 -- remaining suffix that is either null or contains the incomplete last character of the chunk.
@@ -94,7 +95,7 @@
 instance Monoid ByteStringUTF8 where
    mempty = ByteStringUTF8 ByteString.empty
    {-# INLINE mempty #-}
-   ByteStringUTF8 a `mappend` ByteStringUTF8 b = ByteStringUTF8 (a `mappend` b)
+   mappend = (<>)
    {-# INLINE mappend #-}
 
 -- | O(1)
diff --git a/src/Data/Monoid/Instances/Concat.hs b/src/Data/Monoid/Instances/Concat.hs
--- a/src/Data/Monoid/Instances/Concat.hs
+++ b/src/Data/Monoid/Instances/Concat.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2013-2019 Mario Blazevic
+    Copyright 2013-2022 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -7,7 +7,7 @@
 -- | This module defines the monoid transformer data type 'Concat'.
 -- 
 
-{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE Haskell2010, DeriveDataTypeable #-}
 
 module Data.Monoid.Instances.Concat (
    Concat, concatenate, extract, force
@@ -16,6 +16,7 @@
 
 import Control.Applicative -- (Applicative(..))
 import Control.Arrow (first)
+import Data.Data (Data, Typeable)
 import qualified Data.Foldable as Foldable
 import qualified Data.List as List
 import Data.String (IsString(..))
@@ -46,7 +47,7 @@
 --
 data Concat a = Leaf a
               | Concat a :<> Concat a
-              deriving Show
+              deriving (Data, Show, Typeable)
 
 {-# DEPRECATED concatenate, extract "Concat is not wrapping Seq any more, don't use concatenate nor extract." #-}
 concatenate :: PositiveMonoid a => Seq a -> Concat a
diff --git a/src/Data/Monoid/Instances/Measured.hs b/src/Data/Monoid/Instances/Measured.hs
--- a/src/Data/Monoid/Instances/Measured.hs
+++ b/src/Data/Monoid/Instances/Measured.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2013-2019 Mario Blazevic
+    Copyright 2013-2022 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -7,7 +7,7 @@
 -- | This module defines the monoid transformer data type 'Measured'.
 -- 
 
-{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE Haskell2010, DeriveDataTypeable #-}
 
 module Data.Monoid.Instances.Measured (
    Measured, measure, extract
@@ -15,6 +15,7 @@
 where
 
 import Data.Functor -- ((<$>))
+import Data.Data (Data, Typeable)
 import qualified Data.List as List
 import Data.String (IsString(..))
 import Data.Semigroup (Semigroup(..))
@@ -35,7 +36,7 @@
 -- constant-time operation. The parameter is restricted to the 'StableFactorial' class, which guarantees that
 -- @'length' (a <> b) == 'length' a + 'length' b@.
 
-data Measured a = Measured{_measuredLength :: Int, extract :: a} deriving (Eq, Show)
+data Measured a = Measured{_measuredLength :: Int, extract :: a} deriving (Data, Eq, Show, Typeable)
 
 -- | Create a new 'Measured' value.
 measure :: Factorial a => a -> Measured a
diff --git a/src/Data/Monoid/Instances/Positioned.hs b/src/Data/Monoid/Instances/Positioned.hs
--- a/src/Data/Monoid/Instances/Positioned.hs
+++ b/src/Data/Monoid/Instances/Positioned.hs
@@ -1,5 +1,5 @@
 {-
-    Copyright 2014-2021 Mario Blazevic
+    Copyright 2014-2022 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -51,7 +51,7 @@
 
 data OffsetPositioned m = OffsetPositioned{offset :: !Int,
                                            -- ^ the current offset
-                                           extractOffset :: m}
+                                           extractOffset :: m} deriving (Data, Typeable)
 
 data LinePositioned m = LinePositioned{fullOffset :: !Int,
                                        -- | the current line
@@ -502,13 +502,15 @@
    {-# INLINE concatMap #-}
    {-# INLINE foldl' #-}
    {-# INLINE foldr #-}
-   {-# INLINE spanMaybe' #-}
-   {-# INLINE span #-}
+   {-# INLINABLE spanMaybe #-}
+   {-# INLINABLE spanMaybe' #-}
+   {-# INLINABLE span #-}
    {-# INLINE foldl_' #-}
    {-# INLINE foldr_ #-}
    {-# INLINE any #-}
    {-# INLINE all #-}
-   {-# INLINE spanMaybe_' #-}
+   {-# INLINABLE spanMaybe_ #-}
+   {-# INLINABLE spanMaybe_' #-}
    {-# INLINE span_ #-}
    {-# INLINE break_ #-}
    {-# INLINE dropWhile_ #-}
@@ -674,8 +676,9 @@
    {-# INLINE foldr_ #-}
    {-# INLINE any #-}
    {-# INLINE all #-}
-   {-# INLINE spanMaybe_' #-}
-   {-# INLINE span_ #-}
+   {-# INLINABLE spanMaybe_ #-}
+   {-# INLINABLE spanMaybe_' #-}
+   {-# INLINABLE span_ #-}
    {-# INLINE break_ #-}
    {-# INLINE dropWhile_ #-}
    {-# INLINE takeWhile_ #-}
diff --git a/src/Data/Monoid/Instances/Stateful.hs b/src/Data/Monoid/Instances/Stateful.hs
--- a/src/Data/Monoid/Instances/Stateful.hs
+++ b/src/Data/Monoid/Instances/Stateful.hs
@@ -1,5 +1,5 @@
 {-
-    Copyright 2013-2019 Mario Blazevic
+    Copyright 2013-2022 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -12,7 +12,7 @@
 -- >> factors s
 -- >[Stateful ("d",[]),Stateful ("a",[]),Stateful ("t",[]),Stateful ("a",[]),Stateful ("",[4])]
 
-{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE Haskell2010, DeriveDataTypeable #-}
 
 module Data.Monoid.Instances.Stateful (
    Stateful(Stateful), extract, state, setState
@@ -20,6 +20,7 @@
 where
 
 import Control.Applicative -- (Applicative(..))
+import Data.Data (Data, Typeable)
 import Data.Functor -- ((<$>))
 import qualified Data.List as List
 import Data.String (IsString(..))
@@ -41,7 +42,7 @@
 -- | @'Stateful' a b@ is a wrapper around the 'Monoid' @b@ that carries the state @a@ along. The state type @a@ must be
 -- a monoid as well if 'Stateful' is to be of any use. In the 'FactorialMonoid' and 'TextualMonoid' class instances, the
 -- monoid @b@ has the priority and the state @a@ is left for the end.
-newtype Stateful a b = Stateful (b, a) deriving (Eq, Ord, Show)
+newtype Stateful a b = Stateful (b, a) deriving (Data, Eq, Ord, Show, Typeable)
 
 extract :: Stateful a b -> b
 extract (Stateful (t, _)) = t
@@ -63,9 +64,9 @@
    Stateful x <> Stateful y = Stateful (x <> y)
    {-# INLINE (<>) #-}
 
-instance (Monoid a, Monoid b) => Monoid (Stateful a b) where
+instance (Semigroup a, Semigroup b, Monoid a, Monoid b) => Monoid (Stateful a b) where
    mempty = Stateful mempty
-   Stateful x `mappend` Stateful y = Stateful (mappend x y)
+   mappend = (<>)
    {-# INLINE mempty #-}
    {-# INLINE mappend #-}
 
diff --git a/src/Data/Monoid/Monus.hs b/src/Data/Monoid/Monus.hs
--- a/src/Data/Monoid/Monus.hs
+++ b/src/Data/Monoid/Monus.hs
@@ -57,15 +57,14 @@
 -- > stripSuffixOverlap b a <> overlap a b == a
 -- > overlap a b <> stripPrefixOverlap a b == b
 --
--- The result of @overlap a b@ must be the largest prefix of @b@ and suffix of @a@, in the sense that it is contained
--- in any other value @x@ that satifies the property @(x `isPrefixOf` b) && (x `isSuffixOf` a)@:
+-- The result of @overlap a b@ must be the largest prefix of @b@ and suffix of @a@, in the sense that it contains any
+-- other value @x@ that satifies the property @(x `isPrefixOf` b) && (x `isSuffixOf` a)@:
 --
--- > (x `isPrefixOf` overlap a b) && (x `isSuffixOf` overlap a b)
+-- > ∀x. (x `isPrefixOf` b && x `isSuffixOf` a) => (x `isPrefixOf` overlap a b && x `isSuffixOf` overlap a b)
 --
--- and it must be unique so it's not contained in any other value @y@ that satisfies the same property @(y
--- `isPrefixOf` b) && (y `isSuffixOf` a)@:
+-- and it must be unique so there's no other value @y@ that satisfies the same properties for every such @x@:
 --
--- > not ((y `isPrefixOf` overlap a b) && (y `isSuffixOf` overlap a b) && y /= overlap a b)
+-- > ∀y. ((∀x. (x `isPrefixOf` b && x `isSuffixOf` a) => x `isPrefixOf` y && x `isSuffixOf` y) => y == overlap a b)
 --
 -- @since 1.0
 class (Monoid m, LeftReductive m, RightReductive m) => OverlappingGCDMonoid m where
@@ -195,7 +194,7 @@
 instance (OverlappingGCDMonoid a, MonoidNull a) => OverlappingGCDMonoid (Maybe a) where
    overlap (Just a) (Just b) = Just (overlap a b)
    overlap _ _ = Nothing
-   stripOverlap (Just a) (Just b) = (Just a', Just o, Just b')
+   stripOverlap (Just a) (Just b) = (if null a' then Nothing else Just a', Just o, if null b' then Nothing else Just b')
       where (a', o, b') = stripOverlap a b
    stripOverlap a b = (a, Nothing, b)
    stripPrefixOverlap (Just a) (Just b)
@@ -241,8 +240,8 @@
 
 -- | /O(m+n)/
 instance (Ord k, Eq v) => OverlappingGCDMonoid (Map.Map k v) where
-    overlap = Map.intersection
-    stripOverlap a b = (stripPrefixOverlap b a, overlap a b, stripSuffixOverlap a b)
+    overlap = flip Map.intersection
+    stripOverlap a b = (stripSuffixOverlap b a, overlap a b, stripPrefixOverlap a b)
     stripPrefixOverlap = flip Map.difference
     stripSuffixOverlap a b = Map.differenceWith (\x y-> if x == y then Nothing else Just x) b a
 
@@ -250,8 +249,8 @@
 
 -- | /O(m+n)/
 instance Eq a => OverlappingGCDMonoid (IntMap.IntMap a) where
-    overlap = IntMap.intersection
-    stripOverlap a b = (stripPrefixOverlap b a, overlap a b, stripSuffixOverlap a b)
+    overlap = flip IntMap.intersection
+    stripOverlap a b = (stripSuffixOverlap b a, overlap a b, stripPrefixOverlap a b)
     stripPrefixOverlap = flip IntMap.difference
     stripSuffixOverlap a b = IntMap.differenceWith (\x y-> if x == y then Nothing else Just x) b a
 
diff --git a/src/Data/Monoid/Textual.hs b/src/Data/Monoid/Textual.hs
--- a/src/Data/Monoid/Textual.hs
+++ b/src/Data/Monoid/Textual.hs
@@ -274,12 +274,15 @@
    {-# INLINE foldl_ #-}
    {-# INLINE foldl_' #-}
    {-# INLINE foldr_ #-}
-   {-# INLINE spanMaybe_ #-}
-   {-# INLINE spanMaybe_' #-}
+   {-# INLINABLE spanMaybe_ #-}
+   {-# INLINABLE spanMaybe_' #-}
    {-# INLINE span_ #-}
    {-# INLINE break_ #-}
    {-# INLINE takeWhile_ #-}
    {-# INLINE dropWhile_ #-}
+   {-# INLINE elem #-}
+   {-# INLINABLE all #-}
+   {-# INLINABLE any #-}
    {-# MINIMAL splitCharacterPrefix #-}
 
 foldlChars :: TextualMonoid t => (Char -> Char -> Char) -> (t, Char) -> Char -> (t, Char)
diff --git a/src/Data/Semigroup/Cancellative.hs b/src/Data/Semigroup/Cancellative.hs
--- a/src/Data/Semigroup/Cancellative.hs
+++ b/src/Data/Semigroup/Cancellative.hs
@@ -38,6 +38,7 @@
 where
 
 import Data.Semigroup -- (Semigroup, Dual(..), Sum(..), Product(..))
+import Data.Semigroup.Commutative
 import qualified Data.List as List
 import Data.Maybe (isJust)
 import qualified Data.ByteString as ByteString
@@ -52,11 +53,7 @@
 import qualified Data.Set as Set
 import qualified Data.Vector as Vector
 import Numeric.Natural (Natural)
-
--- | Class of all Abelian (/i.e./, commutative) semigroups that satisfy the commutativity property:
--- 
--- > a <> b == b <> a
-class Semigroup m => Commutative m
+import Numeric.Product.Commutative (CommutativeProduct)
 
 -- | Class of Abelian semigroups with a partial inverse for the Semigroup '<>' operation. The inverse operation '</>' must
 -- satisfy the following laws:
@@ -123,8 +120,6 @@
 
 -- Unit instances
 
-instance Commutative ()
-
 instance Reductive () where
    () </> () = Just ()
 
@@ -144,8 +139,6 @@
 
 -- Dual instances
 
-instance Commutative a => Commutative (Dual a)
-
 instance Reductive a => Reductive (Dual a) where
    Dual a </> Dual b = fmap Dual (a </> b)
 
@@ -164,7 +157,6 @@
 instance RightCancellative a => LeftCancellative (Dual a)
 
 -- Sum instances
-instance Num a => Commutative (Sum a)
 
 -- | Helper class to avoid @FlexibleInstances@
 class Num a => SumCancellative a where
@@ -198,24 +190,20 @@
 
 -- Product instances
 
-instance Num a => Commutative (Product a)
-
-instance Integral a => Reductive (Product a) where
+instance (CommutativeProduct a, Integral a) => Reductive (Product a) where
    Product 0 </> Product 0 = Just (Product 0)
    Product _ </> Product 0 = Nothing
    Product a </> Product b = if remainder == 0 then Just (Product quotient) else Nothing
       where (quotient, remainder) = quotRem a b
 
-instance Integral a => LeftReductive (Product a) where
+instance (CommutativeProduct a, Integral a) => LeftReductive (Product a) where
    stripPrefix a b = b </> a
 
-instance Integral a => RightReductive (Product a) where
+instance (CommutativeProduct a, Integral a) => RightReductive (Product a) where
    stripSuffix a b = b </> a
 
 -- Pair instances
 
-instance (Commutative a, Commutative b) => Commutative (a, b)
-
 instance (Reductive a, Reductive b) => Reductive (a, b) where
    (a, b) </> (c, d) = case (a </> c, b </> d)
                        of (Just a', Just b') -> Just (a', b')
@@ -241,8 +229,6 @@
 
 -- Triple instances
 
-instance (Commutative a, Commutative b, Commutative c) => Commutative (a, b, c)
-
 instance (Reductive a, Reductive b, Reductive c) => Reductive (a, b, c) where
    (a1, b1, c1) </> (a2, b2, c2) = (,,) <$> (a1 </> a2) <*> (b1 </> b2) <*> (c1 </> c2)
 
@@ -262,8 +248,6 @@
 
 -- Quadruple instances
 
-instance (Commutative a, Commutative b, Commutative c, Commutative d) => Commutative (a, b, c, d)
-
 instance (Reductive a, Reductive b, Reductive c, Reductive d) => Reductive (a, b, c, d) where
    (a1, b1, c1, d1) </> (a2, b2, c2, d2) = (,,,) <$> (a1 </> a2) <*> (b1 </> b2) <*> (c1 </> c2) <*> (d1 </> d2)
 
@@ -290,9 +274,6 @@
 -- Maybe instances
 
 -- | @since 1.0
-instance Commutative x => Commutative (Maybe x)
-
--- | @since 1.0
 instance Reductive x => Reductive (Maybe x) where
    Just x </> Just y = Just <$> x </> y
    x </> Nothing = Just x
@@ -310,8 +291,6 @@
 
 -- Set instances
 
-instance Ord a => Commutative (Set.Set a)
-
 -- | /O(m*log(n/m + 1)), m <= n/
 instance Ord a => LeftReductive (Set.Set a) where
    isPrefixOf = Set.isSubsetOf
@@ -328,8 +307,6 @@
            | otherwise = Nothing
 
 -- IntSet instances
-
-instance Commutative IntSet.IntSet
 
 -- | /O(m+n)/
 instance LeftReductive IntSet.IntSet where
diff --git a/src/Data/Semigroup/Factorial.hs b/src/Data/Semigroup/Factorial.hs
--- a/src/Data/Semigroup/Factorial.hs
+++ b/src/Data/Semigroup/Factorial.hs
@@ -90,6 +90,15 @@
    foldMap f = foldr (mappend . f) mempty
    reverse s = maybe s sconcat (nonEmpty $ List.reverse $ factors s)
    {-# MINIMAL factors | foldr #-}
+   {-# INLINABLE factors #-}
+   {-# INLINE primePrefix #-}
+   {-# INLINE primeSuffix #-}
+   {-# INLINABLE foldl #-}
+   {-# INLINABLE foldl' #-}
+   {-# INLINABLE foldr #-}
+   {-# INLINE length #-}
+   {-# INLINE foldMap #-}
+   {-# INLINE reverse #-}
 
 -- | A subclass of 'Factorial' whose instances satisfy the following additional laws:
 --
