diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+0.5.3: [2020.02.18]
+-------------------
+* Fix non-terminating GenericSemiring instances
+* Fix incorrect implementation of gtimes' for product types in GSemiring
+* Implement GcdDomain.divide explicitly
+* Remove redundant imports
+* Disambiguate all haddock identifiers
+
 0.5.2: [2019.11.01]
 -------------------
 * Add `gcdExt` function
diff --git a/Data/Euclidean.hs b/Data/Euclidean.hs
--- a/Data/Euclidean.hs
+++ b/Data/Euclidean.hs
@@ -19,19 +19,19 @@
   , gcdExt
   ) where
 
-import Prelude hiding (quotRem, quot, rem, divMod, div, mod, gcd, lcm, negate, (*))
+import Prelude hiding (quotRem, quot, rem, divMod, div, mod, gcd, lcm, negate, (*), Int, Word)
 import qualified Prelude as P
-import Control.Exception
-import Data.Bits
-import Data.Complex
+import Control.Exception (throw, ArithException(..))
+import Data.Bits (Bits)
+import Data.Complex (Complex(..))
 import Data.Int (Int, Int8, Int16, Int32, Int64)
-import Data.Maybe
-import Data.Ratio
-import Data.Semiring
+import Data.Maybe (isJust)
+import Data.Ratio (Ratio)
+import Data.Semiring (Semiring(..), Ring(..), (*), minus, isZero, Mod2)
 import Data.Word (Word, Word8, Word16, Word32, Word64)
-import Foreign.C.Types
-import GHC.Exts
-import GHC.Integer.GMP.Internals
+import Foreign.C.Types (CFloat, CDouble)
+import GHC.Exts (Int(..), Word(..))
+import GHC.Integer.GMP.Internals (gcdInt, gcdWord, gcdInteger, lcmInteger)
 
 import Numeric.Natural
 
@@ -133,7 +133,7 @@
   rem :: a -> a -> a
   rem x y = snd (quotRem x y)
 
-  -- | Euclidean (aka degree, valuation, gauge, norm) function on 'a'. Usually 'fromIntegral' . 'abs'.
+  -- | Euclidean (aka degree, valuation, gauge, norm) function on @a@. Usually @'fromIntegral' '.' 'abs'@.
   --
   -- 'degree' is rarely used by itself. Its purpose
   -- is to provide an evidence of soundness of 'quotRem'
@@ -209,6 +209,7 @@
   negate = P.negate
 
 instance Integral a => GcdDomain (WrappedIntegral a) where
+  divide x y = case x `P.quotRem` y of (q, 0) -> Just q; _ -> Nothing
   gcd     = P.gcd
   lcm     = P.lcm
   coprime = coprimeIntegral
@@ -220,6 +221,7 @@
   rem     = P.rem
 
 instance GcdDomain Int where
+  divide x y = case x `P.quotRem` y of (q, 0) -> Just q; _ -> Nothing
 #if MIN_VERSION_integer_gmp(0,5,1)
   gcd (I# x) (I# y) = I# (gcdInt x y)
 #else
@@ -229,6 +231,7 @@
   coprime = coprimeIntegral
 
 instance GcdDomain Word where
+  divide x y = case x `P.quotRem` y of (q, 0) -> Just q; _ -> Nothing
 #if MIN_VERSION_integer_gmp(1,0,0)
   gcd (W# x) (W# y) = W# (gcdWord x y)
 #else
@@ -238,12 +241,14 @@
   coprime = coprimeIntegral
 
 instance GcdDomain Integer where
+  divide x y = case x `P.quotRem` y of (q, 0) -> Just q; _ -> Nothing
   gcd     = gcdInteger
   lcm     = lcmInteger
   coprime = coprimeIntegral
 
 #define deriveGcdDomain(ty)     \
 instance GcdDomain (ty) where { \
+;  divide x y = case x `P.quotRem` y of { (q, 0) -> Just q; _ -> Nothing } \
 ;  gcd     = P.gcd              \
 ;  lcm     = P.lcm              \
 ;  coprime = coprimeIntegral    \
diff --git a/Data/Field.hs b/Data/Field.hs
--- a/Data/Field.hs
+++ b/Data/Field.hs
@@ -1,4 +1,4 @@
--- | A 'Field' is a 'Ring' in which all nonzero elements
+-- | A 'Field' is a 'Data.Semiring.Ring' in which all nonzero elements
 --   have a multiplicative inverse.
 module Data.Field
   ( -- * Field typeclass
@@ -21,7 +21,7 @@
 -- | Divide two elements of a 'Field'.
 -- For any 'Prelude.Fractional' type, this is the same as '(Prelude./)'.
 --
---     @x `divide` y = x `times` 'recip' y@
+--     @x `divide` y = x `Data.Semiring.times` 'recip' y@
 divide :: Field a => a -> a -> a
 divide = quot
 {-# INLINE divide #-}
@@ -31,7 +31,7 @@
 -- | Invert an element of a 'Field'.
 -- For any 'Prelude.Fractional' type, this is the same as 'Prelude.recip'.
 --
---     @'recip' x `times` x = 'one'@
+--     @'recip' x `Data.Semiring.times` x = 'one'@
 recip :: Field a => a -> a
 recip = quot one
 {-# INLINE recip #-}
diff --git a/Data/Semiring.hs b/Data/Semiring.hs
--- a/Data/Semiring.hs
+++ b/Data/Semiring.hs
@@ -287,7 +287,7 @@
 {-# INLINE product' #-}
 
 -- | Monoid under 'plus'. Analogous to 'Data.Monoid.Sum', but
---   uses the 'Semiring' constraint rather than 'Num'.
+--   uses the 'Semiring' constraint rather than 'Num.Num'.
 newtype Add a = Add { getAdd :: a }
   deriving
     ( Bounded
@@ -330,7 +330,7 @@
   Add' a <> Add' b = Add' (a + b)
 
 -- | Monoid under 'times'. Analogous to 'Data.Monoid.Product', but
---   uses the 'Semiring' constraint rather than 'Num'.
+--   uses the 'Semiring' constraint rather than 'Num.Num'.
 newtype Mul a = Mul { getMul :: a }
   deriving
     ( Bounded
@@ -364,7 +364,7 @@
   {-# INLINE mempty #-}
   {-# INLINE mappend #-}
 
--- | Provide Semiring and Ring for an arbitrary Num. It is useful with GHC 8.6+'s DerivingVia extension.
+-- | Provide Semiring and Ring for an arbitrary 'Num.Num'. It is useful with GHC 8.6+'s DerivingVia extension.
 newtype WrappedNum a = WrapNum { unwrapNum :: a }
   deriving
     ( Bounded
@@ -438,11 +438,11 @@
 -- can think of a semiring as two monoids of the same
 -- underlying type, with the first being commutative.
 -- In the documentation, you will often see the first
--- monoid being referred to as 'additive', and the second
--- monoid being referred to as 'multiplicative', a typical
+-- monoid being referred to as @additive@, and the second
+-- monoid being referred to as @multiplicative@, a typical
 -- convention when talking about semirings.
 --
--- For any type R with a 'Prelude.Num'
+-- For any type R with a 'Num.Num'
 -- instance, the additive monoid is (R, 'Prelude.+', 0)
 -- and the multiplicative monoid is (R, 'Prelude.*', 1).
 --
@@ -496,8 +496,8 @@
 #endif
   negate :: a -> a
 
--- | Subtract two 'Ring' values. For any type 'R' with
--- a 'Prelude.Num' instance, this is the same as '(Prelude.-)'.
+-- | Subtract two 'Ring' values. For any type @R@ with
+-- a 'Num.Num' instance, this is the same as '(Prelude.-)'.
 --
 --     @x `minus` y = x '+' 'negate' y@
 minus :: Ring a => a -> a -> a
@@ -508,7 +508,7 @@
 --
 -- When @{-#@ @LANGUAGE RebindableSyntax #-}@ is enabled,
 -- this function is used for desugaring integer literals.
--- This may be used to facilitate transition from 'Prelude.Num' to 'Ring':
+-- This may be used to facilitate transition from 'Num.Num' to 'Ring':
 -- no need to replace 0 and 1 with 'one' and 'zero'
 -- or to cast numeric literals.
 fromInteger :: Ring a => Integer -> a
diff --git a/Data/Semiring/Generic.hs b/Data/Semiring/Generic.hs
--- a/Data/Semiring/Generic.hs
+++ b/Data/Semiring/Generic.hs
@@ -1,8 +1,9 @@
-{-# LANGUAGE CPP              #-}
+{-# LANGUAGE CPP                  #-}
 #if MIN_VERSION_base(4,6,0)
-{-# LANGUAGE DeriveGeneric    #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeOperators    #-}
+{-# LANGUAGE DeriveGeneric        #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE TypeOperators        #-}
+{-# LANGUAGE UndecidableInstances #-}
 #endif
 
 -- below are safe orphan instances
@@ -48,10 +49,13 @@
 -- | An Identity-style wrapper with a 'Generic' interface
 --   to be used with '-XDerivingVia'.
 newtype GenericSemiring a = GenericSemiring a
-  deriving (Generic)
 
-instance (Semiring a) => Semiring (GenericSemiring a) where
-  zero = gzero; one = gone; plus = gplus; times = gtimes; fromNatural = gfromNatural;
+instance (Generic a, GSemiring (Rep a)) => Semiring (GenericSemiring a) where
+  zero = GenericSemiring gzero
+  one = GenericSemiring gone
+  plus (GenericSemiring x) (GenericSemiring y) = GenericSemiring (gplus x y)
+  times (GenericSemiring x) (GenericSemiring y) = GenericSemiring (gtimes x y)
+  fromNatural x = GenericSemiring (gfromNatural x)
 
 instance (Semiring a, Semiring b) => Semiring (a,b) where
   zero = gzero; one = gone; plus = gplus; times = gtimes; fromNatural = gfromNatural;
@@ -184,7 +188,7 @@
   gzero' = gzero' :*: gzero'
   gone'  = gone'  :*: gone'
   gplus'  (a :*: b) (c :*: d) = gplus'  a c :*: gplus' b d
-  gtimes' (a :*: b) (c :*: d) = gtimes' a c :*: gplus' b d
+  gtimes' (a :*: b) (c :*: d) = gtimes' a c :*: gtimes' b d
   gfromNatural' n = gfromNatural' n :*: gfromNatural' n
 
 instance (GRing a, GRing b) => GRing (a :*: b) where
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.2
+version:       0.5.3
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
