diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+0.2.0.1: [2018.07.28]
+---------------------
+* Add instances for `Op`, `Equivalence`, `Comparison`, and `Predicate` from Data.Functor.Contravariant (upcoming base 4.12.0.0)
+* docfix for (prod -> product, prod' -> product')
+
 0.2.0.0: [2018.07.23]
 ---------------------
 * Fixed the `Semiring` instances of `Set`, `HashSet`, `Vector`, `Storable Vector`, `Unboxed Vector`.
@@ -7,6 +12,8 @@
 * Added newtypes: `Add`, `Mul`
 * Bounds for containers: [0.3,0.6] -> [0.5.4,0.6.0.9]
 * Add semiring instance for `Proxy`
+* names changed: (prod -> product, prod' -> product')
+* sum' and product' now use foldl' instead of foldr'
 
 0.1.2: [2018.05.04]
 -------------------
diff --git a/Data/Semiring.hs b/Data/Semiring.hs
--- a/Data/Semiring.hs
+++ b/Data/Semiring.hs
@@ -17,6 +17,12 @@
 -- this is here because of -XDefaultSignatures
 {-# OPTIONS_GHC -fno-warn-missing-methods #-}
 
+-----------------------------------------------------------------------------
+-- |
+-- A class for semirings (types with two binary operations, one commutative and one associative, and two respective identites), with various general-purpose instances.
+--
+-----------------------------------------------------------------------------
+
 module Data.Semiring
   ( -- * Semiring typeclass
     Semiring(..)
@@ -49,6 +55,9 @@
 import qualified Data.Foldable as Foldable
 import           Data.Function ((.), const, flip, id)
 import           Data.Functor (Functor(..))
+#if MIN_VERSION_base(4,12,0)
+import           Data.Functor.Contravariant (Predicate(..), Comparison(..), Equivalence(..), Op(..))
+#endif
 import           Data.Functor.Identity (Identity(..))
 #if defined(VERSION_unordered_containers)
 import           Data.Hashable (Hashable)
@@ -178,8 +187,8 @@
 sum  = Foldable.foldr plus zero
 {-# INLINE sum #-}
 
--- | The 'prod' function computes the multiplicative sum of the elements in a structure.
---   This function is lazy. for a strict version, see 'prod''.
+-- | 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 = Foldable.foldr times one
 {-# INLINE product #-}
@@ -190,12 +199,14 @@
 sum'  = Foldable.foldl' plus zero
 {-# INLINE sum' #-}
 
--- | The 'prod'' function computes the additive sum of the elements in a structure.
---   This function is strict. For a lazy version, see 'prod'.
+-- | The 'product'' function computes the additive sum of the elements in a structure.
+--   This function is strict. For a lazy version, see 'product'.
 product' :: (Foldable t, Semiring a) => t a -> a
 product' = Foldable.foldl' times one
 {-# INLINE product' #-}
 
+-- | Monoid under 'plus'. Analogous to 'Data.Monoid.Sum', but
+--   uses the 'Semiring' constraint rather than 'Num'.
 newtype Add a = Add { getAdd :: a }
   deriving
     ( Bounded
@@ -220,6 +231,18 @@
     , Typeable
     )
 
+instance Semiring a => Semigroup (Add a) where
+  (<>) = (+)
+  {-# INLINE (<>) #-}
+
+instance Semiring a => Monoid (Add a) where
+  mempty = Add zero
+  mappend = (<>)
+  {-# INLINE mempty #-}
+  {-# INLINE mappend #-}
+
+-- | Monoid under 'times'. Analogous to 'Data.Monoid.Product', but
+--   uses the 'Semiring' constraint rather than 'Num'.
 newtype Mul a = Mul { getMul :: a }
   deriving
     ( Bounded
@@ -244,16 +267,6 @@
     , Typeable
     )
 
-instance Semiring a => Semigroup (Add a) where
-  (<>) = (+)
-  {-# INLINE (<>) #-}
-
-instance Semiring a => Monoid (Add a) where
-  mempty = Add zero
-  mappend = (<>)
-  {-# INLINE mempty #-}
-  {-# INLINE mappend #-}
-
 instance Semiring a => Semigroup (Mul a) where
   (<>) = (*)
   {-# INLINE (<>) #-}
@@ -506,6 +519,21 @@
   {-# INLINE zero  #-}
   {-# INLINE times #-}
   {-# INLINE one   #-}
+
+instance (Ring a, Applicative f) => Ring (Ap f a) where
+  negate = fmap negate
+  {-# INLINE negate #-}
+#endif
+
+#if MIN_VERSION_base(4,12,0)
+deriving instance Semiring (Predicate a)
+deriving instance Ring (Predicate a)
+
+deriving instance Semiring a => Semiring (Equivalence a)
+deriving instance Ring a => Ring (Equivalence a)
+
+deriving instance Semiring a => Semiring (Op a b)
+deriving instance Ring a => Ring (Op a b)
 #endif
 
 instance Semiring Int
diff --git a/Data/Semiring/Free.hs b/Data/Semiring/Free.hs
--- a/Data/Semiring/Free.hs
+++ b/Data/Semiring/Free.hs
@@ -7,6 +7,9 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 #endif
 
+-- | Polynomials with natural number coefficients
+--   form a commutative semiring. In fact, this is
+--   the free commutative semiring.
 module Data.Semiring.Free
   (
 #if defined(VERSION_containers)
@@ -21,11 +24,9 @@
 
 #if defined(VERSION_containers)
 #if MIN_VERSION_base(4,8,0)
-import           Control.Applicative (pure)
 import           Data.Bool (otherwise)
 import           Data.Coerce (Coercible, coerce)
 import           Data.Eq (Eq)
-import           Data.Functor (Functor(..))
 import           Data.Functor.Identity (Identity(..))
 import           Data.Function (flip,id, (.))
 import           Data.Ord (Ord)
@@ -42,23 +43,34 @@
 import           GHC.Real (even, div)
 import           Numeric.Natural
 
+-- | N[x], polynomials with natural number
+--   coefficients form the free commutative semiring
+--   on a single generator {x}.
 newtype Free a = Free
-  { getFree :: Map (Identity a) Natural
+  { getFree :: Map a Natural
   } deriving (Show, Read, Eq, Ord, Semiring)
 
 #if !MIN_VERSION_base(4,9,0)
---deriving instance Semigroup a => Semigroup (Identity a)
 deriving instance Monoid a => Monoid (Identity a)
 #endif
 
+-- | Run a 'Free'
 runFree :: Semiring s => (a -> s) -> Free a -> s
-runFree f = getAdd #. Map.foldMapWithKey ((rep .# Add) . product . fmap f) . getFree
+runFree f = getAdd #.
+  Map.foldMapWithKey
+  ((rep .# Add) . product . Identity . f)
+  . getFree
+{-# INLINE runFree #-}
 
+-- | Run a 'Free', interpreting it in the underlying semiring.
 lowerFree :: Semiring s => Free s -> s
 lowerFree = runFree id
+{-# INLINE lowerFree #-}
 
+-- | Create a 'Free' with one item.
 liftFree :: a -> Free a
-liftFree = Free . flip Map.singleton one . pure
+liftFree = Free . flip Map.singleton one
+{-# INLINE liftFree #-}
 
 rep :: Monoid m => m -> Natural -> m
 rep x = go
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.2.0.0
+version:       0.2.0.1
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
