diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,26 @@
 # Revision history for commutative-semigroups
 
+## 0.1.0.0 -- 2022-06-12
+
+- `Commutative (Product a)` now requires `CommutativeProduct a`.
+  `CommutativeProduct` is a new class to indicate `(*)` from `Num` is
+  commutative, which is not required by `Num`. (Example:
+  multiplication on
+  [quaternions](https://en.wikipedia.org/wiki/Quaternion) is
+  non-commutative, and the `Quaternion a` type from the `linear`
+  package has a valid `instance RealFloat a => Num (Quaternion a)`.)
+
+  **Remark:** There is also no canonical subclass class in the `Num`
+  hierarchy which implies commutative `(*)`, as both `Integral` and
+  `Floating` instances work here:
+
+  - `Integral` instances are customarily Euclidean Domains, which are
+    commutative rings with extra conditions.
+
+  - `Floating` instances customarily expect `(+)`, `(*)`, and `exp` to
+    form an exponential field, which is also a commutative ring with
+    extra conditions.
+
 ## 0.0.2.0 -- 2022-03-26
 
 - Add `instance Ord a => Commutative (Set a)`
diff --git a/commutative-semigroups.cabal b/commutative-semigroups.cabal
--- a/commutative-semigroups.cabal
+++ b/commutative-semigroups.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.4
 name:                commutative-semigroups
-version:             0.0.2.0
+version:             0.1.0.0
 synopsis:            Commutative semigroups
 description:
   A commutative semigroup is a semigroup where the order of arguments to mappend does not matter.
@@ -22,6 +22,7 @@
 
 library
   exposed-modules:     Data.Semigroup.Commutative
+                       Numeric.Product.Commutative
   -- other-modules:
   build-depends:       base >= 4.6 && < 4.17,
                        containers >= 0.4 && < 0.7
diff --git a/src/Data/Semigroup/Commutative.hs b/src/Data/Semigroup/Commutative.hs
--- a/src/Data/Semigroup/Commutative.hs
+++ b/src/Data/Semigroup/Commutative.hs
@@ -24,6 +24,7 @@
 import Data.Functor.Contravariant (Op(Op))
 import GHC.Generics
 #endif
+import Numeric.Product.Commutative ( CommutativeProduct )
 
 -- |An 'Commutative' semigroup is a 'Semigroup' that follows the rule:
 --
@@ -44,7 +45,7 @@
 
 instance Num a => Commutative (Sum a)
 
-instance Fractional a => Commutative (Product a)
+instance CommutativeProduct a => Commutative (Product a)
 
 instance Commutative a => Commutative (Dual a)
 
diff --git a/src/Numeric/Product/Commutative.hs b/src/Numeric/Product/Commutative.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/Product/Commutative.hs
@@ -0,0 +1,104 @@
+{-# LANGUAGE CPP #-}
+module Numeric.Product.Commutative
+  ( CommutativeProduct (..)
+  )
+  where
+
+import Control.Applicative (Const)
+import Data.Complex (Complex)
+import Data.Fixed
+import Data.Functor.Identity
+import Data.Int
+import Data.Ratio (Ratio)
+import Data.Word
+import Numeric.Natural
+
+#if MIN_VERSION_base(4, 9, 0)
+import Data.Semigroup (Max, Min, Product, Sum)
+#endif
+
+#if MIN_VERSION_base(4, 11, 0)
+import Data.Ord (Down)
+#endif
+
+#if MIN_VERSION_base(4, 12, 0)
+import Data.Functor.Contravariant (Op)
+import Data.Monoid (Alt)
+#endif
+
+-- | Subclass of 'Num' where '(*)' is commutative.
+--
+-- 'Num' doesn't demand commutative '(*)', and there are reasonable
+-- "real-world" instances with non-commutative multiplication. There
+-- is also no canonical subclass in @base@ that would suffice, as both
+-- 'Integral' and 'Floating' imply commutative '(*)' for different
+-- reasons.
+--
+-- Two examples of non-commutative '(*)':
+--
+-- * @Linear.Quaternion.Quaterion@ from the @linear@ package has a
+--   'Num' instance, and quaternion multiplication is
+--   noncommutative.
+--
+-- * @Data.Matrix.Matrix@ from the @matrix@ package uses '(*)' for
+--   matrix multiplication, which is also non-commutative (on square
+--   matrices, which is the only time the question makes sense).
+--
+-- @since 0.1.0
+class Num a => CommutativeProduct a
+
+instance CommutativeProduct Int8
+instance CommutativeProduct Int16
+instance CommutativeProduct Int32
+instance CommutativeProduct Int64
+instance CommutativeProduct Int
+instance CommutativeProduct Integer
+
+instance CommutativeProduct Word8
+instance CommutativeProduct Word16
+instance CommutativeProduct Word32
+instance CommutativeProduct Word64
+instance CommutativeProduct Word
+instance CommutativeProduct Natural
+
+instance CommutativeProduct Float
+instance CommutativeProduct Double
+
+instance (RealFloat a, CommutativeProduct a) => CommutativeProduct (Complex a)
+
+instance CommutativeProduct a => CommutativeProduct (Identity a)
+
+-- @since: base-4.7.0.0
+instance CommutativeProduct a => CommutativeProduct (Sum a)
+
+-- @since: base-4.7.0.0
+instance (Integral a, CommutativeProduct a) => CommutativeProduct (Ratio a)
+
+instance (HasResolution a, CommutativeProduct a) => CommutativeProduct (Fixed a)
+
+#if MIN_VERSION_base(4, 9, 0)
+-- @since: base-4.9.0.0
+instance CommutativeProduct a => CommutativeProduct (Min a)
+
+-- @since: base-4.9.0.0
+instance CommutativeProduct a => CommutativeProduct (Max a)
+
+-- @since: base-4.9.0.0
+instance CommutativeProduct a => CommutativeProduct (Product a)
+
+-- @since: base-4.9.0.0
+instance CommutativeProduct a => CommutativeProduct (Const a b)
+#endif
+
+#if MIN_VERSION_base(4, 11, 0)
+-- @since: base-4.11.0.0
+instance CommutativeProduct a => CommutativeProduct (Down a)
+#endif
+
+#if MIN_VERSION_base(4, 12, 0)
+-- @since: base-4.12.0.0
+instance CommutativeProduct a => CommutativeProduct (Op a b)
+
+-- @since: base-4.12.0.0
+instance CommutativeProduct (f a) => CommutativeProduct (Alt f a)
+#endif
