diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,31 @@
+Version 1.2.5
+---------------
+
+* `Data.Monoid.Null.MonoidNull` now has a default implementation
+* Add instances of `MonoidNull` and (where appropriate) `PositiveMonoid` for:
+  - `(a, b, c, d, e)`
+  - `Data.Functor.Compose f g a`
+  - `Data.Functor.Const r a`
+  - `Data.Functor.Identity a`
+  - `Data.Functor.Product f g a`
+  - `Data.Ord.Down a`
+  - `Data.Proxy.Proxy a`
+  - `Data.Semigroup.Max a`
+  - `Data.Semigroup.Min a`
+  - `Data.Semigroup.WrappedMonoid a`
+  - `GHC.Generics.(:*:) f g a`
+  - `GHC.Generics.(:.:) f g a`
+  - `GHC.Generics.K1 i c p`
+  - `GHC.Generics.M1 i c f p`
+  - `GHC.Generics.Par1 p`
+  - `GHC.Generics.Rec1 f p`
+  - `GHC.Generics.U1 p`
+* Added instances of `Reductive` for `Max a`, `Min a`, `Any`, and `All`
+* Bumped the `commutative-semigroups` dependency upper bound
+
 Version 1.2.4.1
 ---------------
-* Bumped the `text` dependency upper bounds
+* Bumped the `text` dependency upper bound
 
 Version 1.2.4
 ---------------
diff --git a/Test/TestMonoidSubclasses.hs b/Test/TestMonoidSubclasses.hs
--- a/Test/TestMonoidSubclasses.hs
+++ b/Test/TestMonoidSubclasses.hs
@@ -23,6 +23,8 @@
 
 import Control.Applicative (Applicative(..), liftA2)
 import Data.Functor ((<$>))
+import Data.Functor.Const (Const(..))
+import Data.Functor.Identity (Identity(..))
 import Data.Foldable (foldMap, toList)
 import Data.Int (Int8, Int32)
 import qualified Data.Foldable as Foldable
@@ -31,6 +33,7 @@
 import qualified Data.List as List
 import Data.Maybe (isJust)
 import Data.Either (lefts, rights)
+import Data.Proxy (Proxy)
 import Data.Tuple (swap)
 import Data.String (IsString, fromString)
 import Data.Char (isLetter)
@@ -64,7 +67,7 @@
 import Data.Monoid.Instances.Positioned (OffsetPositioned, LinePositioned)
 import qualified Data.Monoid.Instances.Positioned as Positioned
 
-import Data.Semigroup (Semigroup, (<>))
+import Data.Semigroup (Semigroup, (<>), Max, Min)
 import Data.Monoid (Monoid, mempty, mconcat, All(All), Any(Any), Dual(Dual),
                     First(First), Last(Last), Sum(Sum), Product(Product))
 import Data.Semigroup.Factorial (Factorial, StableFactorial, 
@@ -206,6 +209,11 @@
                          PositiveMonoidInstance (mempty :: Ordering),
                          PositiveMonoidInstance (mempty :: All),
                          PositiveMonoidInstance (mempty :: Any),
+                         PositiveMonoidInstance (mempty :: Max Int),
+                         PositiveMonoidInstance (mempty :: Min Int),
+                         PositiveMonoidInstance (mempty :: Const String Float),
+                         PositiveMonoidInstance (mempty :: Identity Ordering),
+                         PositiveMonoidInstance (mempty :: (Proxy Float)),
                          PositiveMonoidInstance (mempty :: (Maybe (Sum Integer))),
                          PositiveMonoidInstance (mempty :: (Product Natural)),
                          PositiveMonoidInstance (mempty :: (Sum Natural)),
@@ -317,6 +325,12 @@
 
 reductiveInstances = map upcast cancellativeInstances
                      ++ [ReductiveMonoidInstance (mempty :: Product Integer),
+                         ReductiveMonoidInstance (mempty :: Max Int),
+                         ReductiveMonoidInstance (mempty :: Min Int),
+                         ReductiveMonoidInstance (mempty :: All),
+                         ReductiveMonoidInstance (mempty :: Any),
+                         ReductiveMonoidInstance (mempty :: Identity IntSet),
+                         ReductiveMonoidInstance (mempty :: Const (Sum Int) Float),
                          ReductiveMonoidInstance (mempty :: IntSet),
                          ReductiveMonoidInstance (mempty :: Maybe IntSet),
                          ReductiveMonoidInstance (mempty :: Set Integer)]
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.2.4.1
+Version:             1.2.5
 Cabal-Version:       >= 1.10
 Build-Type:          Simple
 Synopsis:            Subclasses of Monoid
@@ -11,7 +11,7 @@
   
 License:             BSD3
 License-file:        BSD3-LICENSE.txt
-Copyright:           (c) 2013-2023 Mario Blažević
+Copyright:           (c) 2013-2024 Mario Blažević
 Author:              Mario Blažević
 Maintainer:          Mario Blažević <blamario@protonmail.com>
 Homepage:            https://github.com/blamario/monoid-subclasses/
@@ -46,7 +46,7 @@
                      text >= 0.11 && < 1.3 || >= 2.0 && < 2.2,
                      primes == 0.2.*,
                      vector >= 0.12 && < 0.14,
-                     commutative-semigroups >= 0.1 && < 0.2
+                     commutative-semigroups >= 0.1 && < 0.3
   GHC-options:       -Wall
   default-language:  Haskell2010
 
diff --git a/src/Data/Monoid/Null.hs b/src/Data/Monoid/Null.hs
--- a/src/Data/Monoid/Null.hs
+++ b/src/Data/Monoid/Null.hs
@@ -1,20 +1,27 @@
-{- 
+{-
     Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
 
 -- | This module defines the MonoidNull class and some of its instances.
--- 
+--
 
-{-# LANGUAGE Haskell2010, FlexibleInstances, Trustworthy #-}
+{-# LANGUAGE Haskell2010, CPP, FlexibleInstances, DefaultSignatures, Trustworthy #-}
 
 module Data.Monoid.Null (
    MonoidNull(..), PositiveMonoid
    )
 where
-   
+
+import Data.Functor.Compose (Compose(..))
+import Data.Functor.Const (Const(..))
+import Data.Functor.Identity (Identity(..))
 import Data.Monoid -- (Monoid, First(..), Last(..), Dual(..), Sum(..), Product(..), All(getAll), Any(getAny))
+import Data.Ord (Down(..))
+import Data.Proxy (Proxy)
+import Data.Semigroup (Max, Min, WrappedMonoid(..))
+import qualified Data.Functor.Product as Functor
 import qualified Data.List as List
 import qualified Data.ByteString as ByteString
 import qualified Data.ByteString.Lazy as LazyByteString
@@ -26,21 +33,24 @@
 import qualified Data.Sequence as Sequence
 import qualified Data.Set as Set
 import qualified Data.Vector as Vector
+import GHC.Generics ((:*:)(..), (:.:)(..), K1(..), M1(..), Par1(..), Rec1(..), U1)
 import Numeric.Natural (Natural)
 
 import Prelude hiding (null)
 
 -- | Extension of 'Monoid' that allows testing a value for equality with 'mempty'. The following law must hold:
--- 
+--
 -- prop> null x == (x == mempty)
--- 
+--
 -- Furthermore, the performance of this method should be constant, /i.e./, independent of the length of its argument.
 class Monoid m => MonoidNull m where
    null :: m -> Bool
+   default null :: Eq m => m -> Bool
+   null = (==) mempty
 
 -- | Subclass of 'Monoid' for types whose values have no inverse, with the exception of 'Data.Monoid.mempty'. More
 -- formally, the class instances must satisfy the following law:
--- 
+--
 -- prop> null (x <> y) == (null x && null y)
 class MonoidNull m => PositiveMonoid m
 
@@ -73,10 +83,78 @@
 instance (Num a, Eq a) => MonoidNull (Product a) where
    null (Product a) = a == 1
 
+-- | @since 1.2.5.0
+instance (Ord a, Bounded a) => MonoidNull (Max a)
+
+-- | @since 1.2.5.0
+instance (Ord a, Bounded a) => MonoidNull (Min a)
+
 instance Monoid a => MonoidNull (Maybe a) where
    null Nothing = True
    null _ = False
 
+#if MIN_VERSION_base(4, 11, 0)
+-- | @since 1.2.5.0
+instance MonoidNull a => MonoidNull (Down a) where
+   null (Down a) = null a
+#endif
+
+#if MIN_VERSION_base(4, 12, 0)
+-- | @since 1.2.5.0
+instance MonoidNull c => MonoidNull (K1 i c p) where
+   null (K1 c) = null c
+
+-- | @since 1.2.5.0
+instance MonoidNull (f p) => MonoidNull (M1 i c f p) where
+   null (M1 fp) = null fp
+
+-- | @since 1.2.5.0
+instance MonoidNull p => MonoidNull (Par1 p) where
+   null (Par1 p) = null p
+
+-- | @since 1.2.5.0
+instance MonoidNull (f p) => MonoidNull (Rec1 f p) where
+   null (Rec1 fp) = null fp
+
+-- | @since 1.2.5.0
+instance MonoidNull (U1 p) where
+   null _ = True
+
+-- | @since 1.2.5.0
+instance (MonoidNull (f p), MonoidNull (g p)) => MonoidNull ((:*:) f g p) where
+   null (fp :*: gp) = null fp && null gp
+
+-- | @since 1.2.5.0
+instance (MonoidNull (f (g p))) => MonoidNull ((:.:) f g p) where
+   null (Comp1 fgp) = null fgp
+#endif
+
+#if MIN_VERSION_base(4, 16, 0)
+-- | @since 1.2.5.0
+instance MonoidNull (f (g a)) => MonoidNull (Compose f g a) where
+   null (Compose fga) = null fga
+
+-- | @since 1.2.5.0
+instance (MonoidNull (f a), MonoidNull (g a)) => MonoidNull (Functor.Product f g a) where
+   null (Functor.Pair fa ga) = null fa && null ga
+#endif
+
+-- | @since 1.2.5.0
+instance MonoidNull r => MonoidNull (Const r a) where
+   null (Const r) = null r
+
+-- | @since 1.2.5.0
+instance MonoidNull a => MonoidNull (Identity a) where
+   null (Identity a) = null a
+
+-- | @since 1.2.5.0
+instance MonoidNull a => MonoidNull (WrappedMonoid a) where
+   null (WrapMonoid a) = null a
+
+-- | @since 1.2.5.0
+instance MonoidNull (Proxy a) where
+   null _ = True
+
 instance (MonoidNull a, MonoidNull b) => MonoidNull (a, b) where
    null (a, b) = null a && null b
 
@@ -86,6 +164,10 @@
 instance (MonoidNull a, MonoidNull b, MonoidNull c, MonoidNull d) => MonoidNull (a, b, c, d) where
    null (a, b, c, d) = null a && null b && null c && null d
 
+-- | @since 1.2.5.0
+instance (MonoidNull a, MonoidNull b, MonoidNull c, MonoidNull d, MonoidNull e) => MonoidNull (a, b, c, d, e) where
+   null (a, b, c, d, e) = null a && null b && null c && null d && null e
+
 instance MonoidNull [x] where
    null = List.null
 
@@ -133,6 +215,10 @@
 instance PositiveMonoid LazyText.Text
 instance PositiveMonoid (Product Natural)
 instance PositiveMonoid (Sum Natural)
+-- | @since 1.2.5.0
+instance (Ord a, Bounded a) => PositiveMonoid (Min a)
+-- | @since 1.2.5.0
+instance (Ord a, Bounded a) => PositiveMonoid (Max a)
 instance Monoid a => PositiveMonoid (Maybe a)
 instance PositiveMonoid (First a)
 instance PositiveMonoid (Last a)
@@ -144,6 +230,39 @@
 instance PositiveMonoid (Sequence.Seq a)
 instance Ord a => PositiveMonoid (Set.Set a)
 instance PositiveMonoid (Vector.Vector a)
+-- | @since 1.2.5.0
+instance PositiveMonoid r => PositiveMonoid (Const r a)
+-- | @since 1.2.5.0
+instance PositiveMonoid a => PositiveMonoid (Identity a)
+-- | @since 1.2.5.0
+instance PositiveMonoid a => PositiveMonoid (WrappedMonoid a)
+-- | @since 1.2.5.0
+instance PositiveMonoid (Proxy a)
+
+#if MIN_VERSION_base(4, 11, 0)
+-- | @since 1.2.5.0
+instance PositiveMonoid a => PositiveMonoid (Down a)
+#endif
+
+#if MIN_VERSION_base(4, 12, 0)
+-- | @since 1.2.5.0
+instance PositiveMonoid c => PositiveMonoid (K1 i c p)
+-- | @since 1.2.5.0
+instance PositiveMonoid (f p) => PositiveMonoid (M1 i c f p)
+-- | @since 1.2.5.0
+instance PositiveMonoid p => PositiveMonoid (Par1 p)
+-- | @since 1.2.5.0
+instance PositiveMonoid (f p) => PositiveMonoid (Rec1 f p)
+-- | @since 1.2.5.0
+instance PositiveMonoid (U1 p)
+-- | @since 1.2.5.0
+instance (PositiveMonoid (f (g p))) => PositiveMonoid ((:.:) f g p)
+#endif
+
+#if MIN_VERSION_base(4, 16, 0)
+-- | @since 1.2.5.0
+instance PositiveMonoid (f (g a)) => PositiveMonoid (Compose f g a)
+#endif
 
 -- The possible tuple instances would be overlapping, so we leave the choice to the user.
 --
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
@@ -37,6 +37,8 @@
    )
 where
 
+import Data.Functor.Const
+import Data.Functor.Identity
 import Data.Semigroup -- (Semigroup, Dual(..), Sum(..), Product(..))
 import Data.Semigroup.Commutative
 import qualified Data.List as List
@@ -201,6 +203,78 @@
 
 instance (CommutativeProduct a, Integral a) => RightReductive (Product a) where
    stripSuffix a b = b </> a
+
+-- Max & Min instances
+
+instance Ord a => Reductive (Max a) where
+   a </> b = if b <= a then Just a else Nothing
+instance Ord a => Reductive (Min a) where
+   a </> b = if a <= b then Just a else Nothing
+
+instance Ord a => LeftReductive (Max a) where
+   isPrefixOf a b = a <= b
+   stripPrefix a b = b </> a
+instance Ord a => LeftReductive (Min a) where
+   isPrefixOf a b = b <= a
+   stripPrefix a b = b </> a
+
+instance Ord a => RightReductive (Max a) where
+   isSuffixOf a b = a <= b
+   stripSuffix a b = b </> a
+instance Ord a => RightReductive (Min a) where
+   isSuffixOf a b = b <= a
+   stripSuffix a b = b </> a
+
+-- Any & All instances
+
+instance Reductive Any where
+   a </> b = if b <= a then Just a else Nothing
+instance Reductive All where
+   a </> b = if a <= b then Just a else Nothing
+
+instance LeftReductive Any where
+   isPrefixOf a b = a <= b
+   stripPrefix a b = b </> a
+instance LeftReductive All where
+   isPrefixOf a b = b <= a
+   stripPrefix a b = b </> a
+
+instance RightReductive Any where
+   isSuffixOf a b = a <= b
+   stripSuffix a b = b </> a
+instance RightReductive All where
+   isSuffixOf a b = b <= a
+   stripSuffix a b = b </> a
+
+-- Identity & Const instances
+
+instance Reductive a => Reductive (Identity a) where
+   Identity a </> Identity b = Identity <$> (a </> b)
+instance Reductive a => Reductive (Const a x) where
+   Const a </> Const b = Const <$> (a </> b)
+
+instance Cancellative a => Cancellative (Identity a)
+instance Cancellative a => Cancellative (Const a x)
+
+instance LeftReductive a => LeftReductive (Identity a) where
+   stripPrefix (Identity a) (Identity b) = Identity <$> stripPrefix a b
+   isPrefixOf (Identity a) (Identity b) = isPrefixOf a b
+instance LeftReductive a => LeftReductive (Const a x) where
+   stripPrefix (Const a) (Const b) = Const <$> stripPrefix a b
+   isPrefixOf (Const a) (Const b) = isPrefixOf a b
+
+instance RightReductive a => RightReductive (Identity a) where
+   stripSuffix (Identity a) (Identity b) = Identity <$> stripSuffix a b
+   isSuffixOf (Identity a) (Identity b) = isSuffixOf a b
+instance RightReductive a => RightReductive (Const a x) where
+   stripSuffix (Const a) (Const b) = Const <$> stripSuffix a b
+   isSuffixOf (Const a) (Const b) = isSuffixOf a b
+
+instance LeftCancellative a => LeftCancellative (Identity a)
+instance LeftCancellative a => LeftCancellative (Const a x)
+
+instance RightCancellative a => RightCancellative (Identity a)
+instance RightCancellative a => RightCancellative (Const a x)
 
 -- Pair instances
 
