diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+0.5.4: [2020.07.13]
+-------------------
+* Drop support for GHCs prior to 7.10
+* Add default quotRem implementation
+* Expose Data.Semiring.Generic.gfromNatural
+
 0.5.3: [2020.02.18]
 -------------------
 * Fix non-terminating GenericSemiring instances
diff --git a/Data/Euclidean.hs b/Data/Euclidean.hs
--- a/Data/Euclidean.hs
+++ b/Data/Euclidean.hs
@@ -60,7 +60,6 @@
 -- >   quotRem = ...
 -- >   degree  = ...
 class Semiring a => GcdDomain a where
-
   -- | Division without remainder.
   --
   -- prop> \x y -> (x * y) `divide` y == Just x
@@ -116,10 +115,12 @@
 -- <https://en.wikipedia.org/wiki/Euclidean_domain Euclidean domain>
 -- endowed by a given Euclidean function 'degree'.
 class GcdDomain a => Euclidean a where
+  {-# MINIMAL (quotRem | quot, rem), degree #-}
   -- | Division with remainder.
   --
   -- prop> \x y -> y == 0 || let (q, r) = x `quotRem` y in x == q * y + r
   quotRem :: a -> a -> (a, a)
+  quotRem x y = (quot x y, rem x y)
 
   -- | Division. Must match its default definition:
   --
diff --git a/Data/Semiring.hs b/Data/Semiring.hs
--- a/Data/Semiring.hs
+++ b/Data/Semiring.hs
@@ -11,9 +11,6 @@
 {-# LANGUAGE Rank2Types                 #-}
 {-# LANGUAGE ScopedTypeVariables        #-}
 {-# LANGUAGE StandaloneDeriving         #-}
-#if MIN_VERSION_base(4,7,0) && !MIN_VERSION_base(4,8,0)
-{-# LANGUAGE UndecidableInstances       #-} -- on GHC 7.8 the coercible constraint causes us to need this
-#endif
 
 -----------------------------------------------------------------------------
 -- |
@@ -41,7 +38,7 @@
   , Mul(..)
   , WrappedNum(..)
   , Mod2(..)
-#if defined(VERSION_containers) && MIN_VERSION_base(4,7,0)
+#if defined(VERSION_containers)
   , IntSetOf(..)
   , IntMapOf(..)
 #endif
@@ -57,9 +54,7 @@
 import           Control.Applicative (Applicative(..), Const(..), liftA2)
 import           Data.Bits (Bits)
 import           Data.Bool (Bool(..), (||), (&&), otherwise)
-#if MIN_VERSION_base(4,7,0)
 import           Data.Coerce (Coercible, coerce)
-#endif
 import           Data.Complex (Complex(..))
 import           Data.Eq (Eq(..))
 import           Data.Fixed (Fixed, HasResolution)
@@ -98,12 +93,10 @@
 #endif
 import           Data.Monoid (Monoid(..), Dual(..))
 import           Data.Ord (Ord((<)), (>=))
-#if MIN_VERSION_base(4,6,0)
 import           Data.Ord (Down(..))
-#endif
 import           Data.Proxy (Proxy(..))
 import           Data.Ratio (Ratio, Rational, (%))
-import           Data.Semigroup (Semigroup(..))
+import           Data.Semigroup.Compat (Semigroup(..))
 #if defined(VERSION_containers)
 import           Data.Set (Set)
 import qualified Data.Set as Set
@@ -123,9 +116,7 @@
 import           GHC.Enum (Enum, Bounded)
 import           GHC.Err (error)
 import           GHC.Float (Float, Double)
-#if MIN_VERSION_base(4,6,1)
 import           GHC.Generics (Generic,Generic1)
-#endif
 import           GHC.IO (IO)
 import           GHC.Integer (Integer)
 import qualified GHC.Num as Num
@@ -241,7 +232,6 @@
 foldMapT f = Foldable.foldr (times . f) one
 {-# INLINE foldMapT #-}
 
-#if MIN_VERSION_base(4,7,0)
 infixr 9 #.
 (#.) :: Coercible b c => (b -> c) -> (a -> b) -> a -> c
 (#.) _ = coerce
@@ -258,22 +248,6 @@
 product = getMul #. foldMap Mul
 {-# INLINE product #-}
 
-#else
-
--- | The 'sum' function computes the additive sum of the elements in a structure.
---   This function is lazy. For a strict version, see 'sum''.
-sum :: (Foldable t, Semiring a) => t a -> a
-sum = getAdd . foldMap Add
-{-# INLINE sum #-}
-
--- | The 'product' function computes the product of the elements in a structure.
---   This function is lazy. for a strict version, see 'product''.
-product :: (Foldable t, Semiring a) => t a -> a
-product = getMul . foldMap Mul
-{-# INLINE product #-}
-
-#endif
-
 -- | The 'sum'' function computes the additive sum of the elements in a structure.
 --   This function is strict. For a lazy version, see 'sum'.
 sum'  :: (Foldable t, Semiring a) => t a -> a
@@ -296,10 +270,8 @@
     , Foldable
     , Fractional
     , Functor
-#if MIN_VERSION_base(4,6,1)
     , Generic
     , Generic1
-#endif
     , Num.Num
     , Ord
     , Read
@@ -339,10 +311,8 @@
     , Foldable
     , Fractional
     , Functor
-#if MIN_VERSION_base(4,6,1)
     , Generic
     , Generic1
-#endif
     , Num.Num
     , Ord
     , Read
@@ -373,10 +343,8 @@
     , Foldable
     , Fractional
     , Functor
-#if MIN_VERSION_base(4,6,1)
     , Generic
     , Generic1
-#endif
     , Num.Num
     , Ord
     , Read
@@ -410,9 +378,7 @@
     , Ord
     , Read
     , Show
-#if MIN_VERSION_base(4,6,1)
     , Generic
-#endif
     )
 
 instance Semiring Mod2 where
@@ -785,9 +751,7 @@
   {-# INLINE times #-}
   {-# INLINE fromNatural #-}
 deriving instance Semiring a => Semiring (Identity a)
-#if MIN_VERSION_base(4,6,0)
 deriving instance Semiring a => Semiring (Down a)
-#endif
 instance HasResolution a => Semiring (Fixed a) where
   zero  = 0
   one   = 1
@@ -868,9 +832,7 @@
   negate = Num.negate
   {-# INLINE negate #-}
 
-#if MIN_VERSION_base(4,6,0)
 deriving instance Ring a => Ring (Down a)
-#endif
 deriving instance Ring a => Ring (Identity a)
 instance HasResolution a => Ring (Fixed a) where
   negate = Num.negate
@@ -900,17 +862,14 @@
   {-# INLINE one   #-}
   {-# INLINE fromNatural #-}
 
-#if MIN_VERSION_base(4,7,0)
 -- | Wrapper to mimic 'Set' ('Data.Semigroup.Sum' 'Int'),
 -- 'Set' ('Data.Semigroup.Product' 'Int'), etc.,
 -- while having a more efficient underlying representation.
 newtype IntSetOf a = IntSetOf { getIntSet :: IntSet }
   deriving
     ( Eq
-#if MIN_VERSION_base(4,6,1)
     , Generic
     , Generic1
-#endif
     , Ord
     , Read
     , Show
@@ -936,7 +895,6 @@
   {-# INLINE times #-}
   {-# INLINE one   #-}
   {-# INLINE fromNatural #-}
-#endif
 
 -- | The multiplication laws are satisfied for
 --   any underlying 'Monoid' as the key type,
@@ -961,17 +919,14 @@
   {-# INLINE one   #-}
   {-# INLINE fromNatural #-}
 
-#if MIN_VERSION_base(4,7,0)
 -- | Wrapper to mimic 'Map' ('Data.Semigroup.Sum' 'Int') v,
 -- 'Map' ('Data.Semigroup.Product' 'Int') v, etc.,
 -- while having a more efficient underlying representation.
 newtype IntMapOf k v = IntMapOf { getIntMap :: IntMap v }
   deriving
     ( Eq
-#if MIN_VERSION_base(4,6,1)
     , Generic
     , Generic1
-#endif
     , Ord
     , Read
     , Show
@@ -997,7 +952,6 @@
   {-# INLINE times #-}
   {-# INLINE one   #-}
   {-# INLINE fromNatural #-}
-#endif
 
 #endif
 
diff --git a/Data/Semiring/Generic.hs b/Data/Semiring/Generic.hs
--- a/Data/Semiring/Generic.hs
+++ b/Data/Semiring/Generic.hs
@@ -33,6 +33,7 @@
   , gone
   , gplus
   , gtimes
+  , gfromNatural
   , GRing(..)
   , gnegate
   , GenericSemiring(..)
diff --git a/semirings.cabal b/semirings.cabal
--- a/semirings.cabal
+++ b/semirings.cabal
@@ -1,6 +1,6 @@
 name:          semirings
 category:      Algebra, Data, Data Structures, Math, Maths, Mathematics
-version:       0.5.3
+version:       0.5.4
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
@@ -29,30 +29,13 @@
 
 build-type:    Simple
 extra-source-files: README.md CHANGELOG.md
-tested-with:   GHC == 7.4.1
-             , GHC == 7.4.2
-             , GHC == 7.6.1
-             , GHC == 7.6.2
-             , GHC == 7.8.1
-             , GHC == 7.8.3
-             , GHC == 7.8.4
-             , GHC == 7.10.1
-             , GHC == 7.10.2
-             , GHC == 7.10.3
-             , GHC == 8.0.1
+tested-with:   GHC == 7.10.3
              , GHC == 8.0.2
-             , GHC == 8.2.1
              , GHC == 8.2.2
-             , GHC == 8.4.1
-             , GHC == 8.4.2
-             , GHC == 8.4.3
              , GHC == 8.4.4
-             , GHC == 8.6.1
-             , GHC == 8.6.2
-             , GHC == 8.6.3
-             , GHC == 8.6.4
              , GHC == 8.6.5
-             , GHC == 8.8.1
+             , GHC == 8.8.3
+             , GHC == 8.10.1
 
 source-repository head
   type: git
@@ -89,39 +72,25 @@
   ghc-options: -Wall
 
   build-depends:
-      base >= 4.5 && < 5
-    , integer-gmp
-
-  if impl(ghc < 7.10)
-    build-depends:
-        nats >= 0.1 && < 2
-      , transformers
-
-  if impl(ghc < 8.0)
-    build-depends: semigroups >= 0.17
-
-  if impl(ghc < 7.8)
-    build-depends: tagged
-
-  if impl(ghc >= 7.2)
-    exposed-modules:
-      Data.Euclidean
-      Data.Field
-      Data.Semiring
-      Data.Star
-      Data.Semiring.Tropical
-  if impl(ghc >= 7.6.1)
-    exposed-modules:
-      Data.Semiring.Generic
+      base >= 4.8 && < 5
+    , base-compat-batteries
+    , integer-gmp >= 0.1.0.0
+  exposed-modules:
+    Data.Euclidean
+    Data.Field
+    Data.Semiring
+    Data.Star
+    Data.Semiring.Tropical
+    Data.Semiring.Generic
 
-    if flag(containers) && impl(ghc >= 7.8)
-      build-depends: containers >= 0.5.4 && < 0.7
+  if flag(containers)
+    build-depends: containers >= 0.5.4 && < 0.7
 
-    if flag(hashable) && impl(ghc < 7.8)
-      build-depends: hashable >= 1.1  && < 1.4
+  if flag(hashable)
+    build-depends: hashable >= 1.1  && < 1.4
 
-    if flag(hashable) && impl(ghc >= 7.8)
-      build-depends: hashable >= 1.1  && < 1.4
+  if flag(hashable)
+    build-depends: hashable >= 1.1  && < 1.4
 
-    if flag(hashable) && flag(unordered-containers)
-      build-depends: unordered-containers >= 0.2  && < 0.3
+  if flag(hashable) && flag(unordered-containers)
+    build-depends: unordered-containers >= 0.2  && < 0.3
