diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,10 @@
+0.16.2
+------
+* Added `genericMappend` and supporting `GSemigroup` class for generically deriving Semigroup instances.
+* Added `Arg a b` which only compares for equality/order on its first argument, which can be used to compute `argmin` and `argmax`.
+* Add `Bifunctor` `Arg` instance to avoid orphans for GHC 7.10+.
+* Added missing `Data.Monoid.Generic` module to source control.
+
 0.16.1
 ------
 * Added `Semigroup` instances for various Builder constructions in `text` and `bytestring` where available.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2011-2014 Edward Kmett
+Copyright 2011-2015 Edward Kmett
 
 All rights reserved.
 
diff --git a/semigroups.cabal b/semigroups.cabal
--- a/semigroups.cabal
+++ b/semigroups.cabal
@@ -1,6 +1,6 @@
 name:          semigroups
 category:      Algebra, Data, Data Structures, Math
-version:       0.16.1
+version:       0.16.2
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
@@ -9,7 +9,7 @@
 stability:     provisional
 homepage:      http://github.com/ekmett/semigroups/
 bug-reports:   http://github.com/ekmett/semigroups/issues
-copyright:     Copyright (C) 2011-2014 Edward A. Kmett
+copyright:     Copyright (C) 2011-2015 Edward A. Kmett
 synopsis:      Anything that associates
 description:
     In mathematics, a semigroup is an algebraic structure consisting of a set together with an associative binary operation. A semigroup generalizes a monoid in that there might not exist an identity element. It also (originally) generalized a group (a monoid with all inverses) to a type where every element did not have to have an inverse, thus the name semigroup.
@@ -80,6 +80,10 @@
   exposed-modules:
     Data.Semigroup
     Data.List.NonEmpty
+
+  if impl(ghc >= 7.4)
+    exposed-modules:
+      Data.Semigroup.Generic
 
   build-depends:
     base >= 2   && < 5,
diff --git a/src/Data/List/NonEmpty.hs b/src/Data/List/NonEmpty.hs
--- a/src/Data/List/NonEmpty.hs
+++ b/src/Data/List/NonEmpty.hs
@@ -24,7 +24,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.List.NonEmpty
--- Copyright   :  (C) 2011-2014 Edward Kmett,
+-- Copyright   :  (C) 2011-2015 Edward Kmett,
 --                (C) 2010 Tony Morris, Oliver Taylor, Eelis van der Weegen
 -- License     :  BSD-style (see the file LICENSE)
 --
@@ -172,6 +172,7 @@
 #endif
 #ifdef LANGUAGE_DeriveGeneric
   , Generic
+  , Generic1
 #endif
   )
 
diff --git a/src/Data/Semigroup.hs b/src/Data/Semigroup.hs
--- a/src/Data/Semigroup.hs
+++ b/src/Data/Semigroup.hs
@@ -5,7 +5,7 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 #endif
 
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 702
 #define LANGUAGE_DefaultSignatures
 {-# LANGUAGE DefaultSignatures #-}
 #if defined(MIN_VERSION_hashable) || __GLASGOW_HASKELL__ >= 708
@@ -15,21 +15,26 @@
 #endif
 #endif
 
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704
+#if __GLASGOW_HASKELL__ >= 704
 #define LANGUAGE_DeriveGeneric
 {-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts #-}
 #endif
 
-
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
+#if __GLASGOW_HASKELL__ >= 708
 #define USE_COERCE
 {-# LANGUAGE ScopedTypeVariables #-}
 #endif
 
+#ifndef MIN_VERSION_base
+#define MIN_VERSION_base(x,y,z) 1
+#endif
+
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Semigroup
--- Copyright   :  (C) 2011-2014 Edward Kmett
+-- Copyright   :  (C) 2011-2015 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
@@ -74,9 +79,18 @@
   -- * Difference lists of a semigroup
   , diff
   , cycle1
+  -- * ArgMin, ArgMax
+  , Arg(..)
+  , ArgMin
+  , ArgMax
   ) where
 
 import Prelude hiding (foldr1)
+
+#if MIN_VERSION_base(4,8,0)
+import Data.Bifunctor
+#endif
+
 import Data.Monoid (Monoid(..),Dual(..),Endo(..),All(..),Any(..),Sum(..),Product(..))
 import Control.Applicative
 import Control.Monad
@@ -307,6 +321,7 @@
 instance Semigroup (NonEmpty a) where
   (a :| as) <> ~(b :| bs) = a :| (as ++ b : bs)
 
+
 newtype Min a = Min { getMin :: a } deriving
   ( Eq, Ord, Show, Read
 #ifdef LANGUAGE_DeriveDataTypeable
@@ -314,6 +329,7 @@
 #endif
 #ifdef LANGUAGE_DeriveGeneric
   , Generic
+  , Generic1
 #endif
   )
 
@@ -387,6 +403,7 @@
 #endif
 #ifdef LANGUAGE_DeriveGeneric
   , Generic
+  , Generic1
 #endif
   )
 
@@ -453,6 +470,62 @@
   rnf (Max a) = rnf a
 #endif
 
+-- | 'Arg' isn't itself a 'Semigroup' in its own right, but it can be placed inside 'Min' and 'Max'
+-- to compute an arg min or arg max.
+data Arg a b = Arg a b deriving
+  ( Show, Read
+#ifdef LANGUAGE_DeriveDataTypeable
+  , Data, Typeable
+#endif
+#ifdef LANGUAGE_DeriveGeneric
+  , Generic
+  , Generic1
+#endif
+  )
+
+type ArgMin a b = Min (Arg a b)
+type ArgMax a b = Max (Arg a b)
+
+instance Functor (Arg a) where
+  fmap f (Arg x a) = Arg x (f a)
+
+instance Foldable (Arg a) where
+  foldMap f (Arg _ a) = f a
+
+instance Traversable (Arg a) where
+  traverse f (Arg x a) = Arg x <$> f a
+
+instance Eq a => Eq (Arg a b) where
+  Arg a _ == Arg b _ = a == b
+
+instance Ord a => Ord (Arg a b) where
+  Arg a _ `compare` Arg b _ = compare a b
+  min x@(Arg a _) y@(Arg b _)
+    | a <= b    = x
+    | otherwise = y
+  max x@(Arg a _) y@(Arg b _)
+    | a >= b    = x
+    | otherwise = y
+
+#ifdef MIN_VERSION_deepseq
+instance (NFData a, NFData b) => NFData (Arg a b) where
+  rnf (Arg a b) = rnf a `seq` rnf b `seq` ()
+#endif
+
+#ifdef MIN_VERSION_hashable
+instance (Hashable a, Hashable b) => Hashable (Arg a b) where
+#if MIN_VERSION_hashable(1,2,0)
+  hashWithSalt p (Arg a b) = hashWithSalt p a `hashWithSalt` b
+#else
+  hash (Arg a b) = hashWithSalt (hash a) b
+#endif
+#endif
+
+#if MIN_VERSION_base(4,8,0)
+instance Bifunctor Arg where
+  bimap f g (Arg a b) = Arg (f a) (g b)
+#endif
+
 -- | Use @'Option' ('First' a)@ to get the behavior of 'Data.Monoid.First' from @Data.Monoid@.
 newtype First a = First { getFirst :: a } deriving
   ( Eq, Ord, Show, Read
@@ -462,6 +535,7 @@
 #endif
 #ifdef LANGUAGE_DeriveGeneric
   , Generic
+  , Generic1
 #endif
   )
 
@@ -528,6 +602,7 @@
 #endif
 #ifdef LANGUAGE_DeriveGeneric
   , Generic
+  , Generic1
 #endif
   )
 
@@ -636,6 +711,7 @@
 #endif
 #ifdef LANGUAGE_DeriveGeneric
   , Generic
+  , Generic1
 #endif
   )
 
@@ -701,6 +777,7 @@
 #endif
 #ifdef LANGUAGE_DeriveGeneric
   , Generic
+  , Generic1
 #endif
   )
 
diff --git a/src/Data/Semigroup/Generic.hs b/src/Data/Semigroup/Generic.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Semigroup/Generic.hs
@@ -0,0 +1,82 @@
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE Safe #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Semigroup.Generic
+-- Copyright   :  (C) 2014-2015 Edward Kmett, Eric Mertens
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- This module provides generic deriving tools for monoids and semigroups for
+-- product-like structures.
+--
+----------------------------------------------------------------------------
+module Data.Semigroup.Generic
+  ( GSemigroup
+  , gmappend
+  , GMonoid
+  , gmempty
+  ) where
+
+import Data.Semigroup
+import GHC.Generics
+
+-- | Generically generate a 'Semigroup' ('<>') operation for any type
+-- implementing 'Generic'. This operation will append two values
+-- by point-wise appending their component fields. It is only defined
+-- for product types.
+--
+-- @
+-- 'gmappend' a ('gmappend' b c) = 'gmappend' ('gmappend' a b) c
+-- @
+gmappend :: (Generic a, GSemigroup (Rep a)) => a -> a -> a
+gmappend x y = to (gmappend' (from x) (from y))
+
+class GSemigroup f where
+  gmappend' :: f p -> f p -> f p
+
+instance GSemigroup U1 where
+  gmappend' _ _ = U1
+
+instance GSemigroup V1 where
+  gmappend' x y = x `seq` y `seq` error "GSemigroup.V1: gmappend'"
+
+instance Semigroup a => GSemigroup (K1 i a) where
+  gmappend' (K1 x) (K1 y) = K1 (x <> y)
+
+instance GSemigroup f => GSemigroup (M1 i c f) where
+  gmappend' (M1 x) (M1 y) = M1 (gmappend' x y)
+
+instance (GSemigroup f, GSemigroup g) => GSemigroup (f :*: g) where
+  gmappend' (x1 :*: x2) (y1 :*: y2) = gmappend' x1 y1 :*: gmappend' x2 y2
+
+-- | Generically generate a 'Monoid' 'mempty' for any product-like type
+-- implementing 'Generic'.
+--
+-- It is only defined for product types.
+--
+-- @
+-- 'gmappend' 'gmempty' a = a = 'gmappend' a 'gmempty'
+-- @
+
+gmempty :: (Generic a, GMonoid (Rep a)) => a
+gmempty = to gmempty'
+
+class GSemigroup f => GMonoid f where
+  gmempty' :: f p
+
+instance GMonoid U1 where
+  gmempty' = U1
+
+instance (Semigroup a, Monoid a) => GMonoid (K1 i a) where
+  gmempty' = K1 mempty
+
+instance GMonoid f => GMonoid (M1 i c f) where
+  gmempty' = M1 gmempty'
+
+instance (GMonoid f, GMonoid g) => GMonoid (f :*: g) where
+  gmempty' = gmempty' :*: gmempty'
