diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,6 +14,14 @@
 
 matrix:
   include:
+    - env: CABALVER=1.18 GHCVER=7.0.4 BUILD=cabal
+      compiler: ": #GHC 7.0.4"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.0.4,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+
+    - env: CABALVER=1.18 GHCVER=7.2.2 BUILD=cabal
+      compiler: ": #GHC 7.2.2"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.2.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+
     - env: CABALVER=1.18 GHCVER=7.4.2 BUILD=cabal
       compiler: ": #GHC 7.4.2"
       addons: {apt: {packages: [cabal-install-1.18,ghc-7.4.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
@@ -32,21 +40,29 @@
 #    - env: BUILD=stack STACK_YAML=stack-7.8.yaml
 #      os: osx
 
-    - env: CABALVER=1.22 GHCVER=7.10.1 BUILD=cabal
-      compiler: ": #GHC 7.10.1"
-      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.1,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+    - env: CABALVER=1.22 GHCVER=7.10.3 BUILD=cabal
+      compiler: ": #GHC 7.10.3"
+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
 
-    - env: CABALVER=1.22 GHCVER=7.10.2 BUILD=cabal
-      compiler: ": #GHC 7.10.2"
-      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=8.0.2 BUILD=cabal
+      compiler: ": #GHC 8.0.2"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
 
-    - env: BUILD=stack STACK_OPTIONS=--skip-ghc-check
-      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=head BUILD=cabal
+      compiler: ": #GHC head"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-head,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
 
-    - env: BUILD=stack
-      os: osx
+#    - env: BUILD=stack STACK_OPTIONS=--skip-ghc-check
+#      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
 
+#    - env: BUILD=stack
+#      os: osx
 
+  allow_failures:
+    - env: CABALVER=1.18 GHCVER=7.0.4 BUILD=cabal
+    - env: CABALVER=1.18 GHCVER=7.2.2 BUILD=cabal
+    - env: CABALVER=1.24 GHCVER=head BUILD=cabal
+
 before_install:
  - unset CC
  - case "$BUILD" in
@@ -87,7 +103,7 @@
          rm -rf $HOME/.cabsnap;
          mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
          cabal install --only-dependencies --enable-tests --enable-benchmarks;
-         if [ "$GHCVER" = "7.10.1" ]; then cabal install Cabal-1.22.4.0; fi;
+         if [ "$GHCVER" = "7.10.3" ]; then cabal install Cabal-1.22.4.0; fi;
        fi;
        if [ ! -d $HOME/.cabsnap ]; then
          echo "snapshotting package-db to build-cache";
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,8 @@
+0.5.1
+-----
+* Add `Distributive` instances for datatypes from `Data.Semigroup` and `GHC.Generics`
+* Add `MINIMAL` pragma for `Distributive`
+
 0.5.0.2
 -------
 * A more elegant fix for builds on GHC 7.2
diff --git a/distributive.cabal b/distributive.cabal
--- a/distributive.cabal
+++ b/distributive.cabal
@@ -1,6 +1,6 @@
 name:          distributive
 category:      Data Structures
-version:       0.5.0.2
+version:       0.5.1
 license:       BSD3
 cabal-version: >= 1.8
 license-file:  LICENSE
@@ -25,6 +25,14 @@
   type: git
   location: git://github.com/ekmett/distributive.git
 
+flag semigroups
+  manual: True
+  default: True
+  description:
+    You can disable the use of the `tagged` package using `-f-tagged`.
+    .
+    Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.
+
 flag tagged
   manual: True
   default: True
@@ -52,6 +60,10 @@
 
   if impl(ghc>=7.2 && < 7.6)
     build-depends: ghc-prim
+
+  if impl(ghc < 8.0)
+    if flag(semigroups)
+      build-depends: semigroups >= 0.11 && < 1
 
   ghc-options: -Wall
 
diff --git a/src/Data/Distributive.hs b/src/Data/Distributive.hs
--- a/src/Data/Distributive.hs
+++ b/src/Data/Distributive.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeOperators #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Distributive
@@ -15,12 +16,13 @@
   ( Distributive(..)
   , cotraverse
   , comapM
+  , fmapCollect
   ) where
 
 import Control.Applicative
 import Control.Applicative.Backwards
 import Control.Monad (liftM)
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 707
+#if __GLASGOW_HASKELL__ < 707
 import Control.Monad.Instances ()
 #endif
 import Control.Monad.Trans.Identity
@@ -35,12 +37,18 @@
 #if MIN_VERSION_base(4,4,0)
 import Data.Complex
 #endif
-#if (defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707) || defined(MIN_VERSION_tagged)
+#if __GLASGOW_HASKELL__ >= 707 || defined(MIN_VERSION_tagged)
 import Data.Proxy
 #endif
+#if __GLASGOW_HASKELL__ >= 800 || defined(MIN_VERSION_semigroups)
+import qualified Data.Semigroup as Semigroup
+#endif
 #ifdef MIN_VERSION_tagged
 import Data.Tagged
 #endif
+#if __GLASGOW_HASKELL__ >= 702
+import GHC.Generics (U1(..), (:*:)(..), (:.:)(..), Par1(..), Rec1(..), M1(..))
+#endif
 
 #ifdef HLINT
 {-# ANN module "hlint: ignore Use section" #-}
@@ -53,9 +61,7 @@
 -- some Coapplicative class. Categorically every 'Distributive'
 -- functor is actually a right adjoint, and so it must be 'Representable'
 -- endofunctor and preserve all limits. This is a fancy way of saying it
--- isomorphic to `(->) x` for some x.
---
--- Minimal complete definition: 'distribute' or 'collect'
+-- isomorphic to @(->) x@ for some x.
 --
 -- To be distributable a container will need to have a way to consistently
 -- zip a potentially infinite number of copies of itself. This effectively
@@ -64,54 +70,77 @@
 -- and no extra information to try to merge together.
 --
 class Functor g => Distributive g where
+#if __GLASGOW_HASKELL__ >= 707
+  {-# MINIMAL distribute | collect #-}
+#endif
   -- | The dual of 'Data.Traversable.sequenceA'
   --
   -- >>> distribute [(+1),(+2)] 1
   -- [2,3]
   --
-  -- @'distribute' = 'collect' 'id'@
+  -- @
+  -- 'distribute' = 'collect' 'id'
+  -- 'distribute' . 'distribute' = 'id'
+  -- @
   distribute  :: Functor f => f (g a) -> g (f a)
   distribute  = collect id
 
   -- |
-  -- @'collect' f = 'distribute' . 'fmap' f@
+  -- @
+  -- 'collect' f = 'distribute' . 'fmap' f
+  -- 'fmap' f = 'runIdentity' . 'collect' ('Identity' . f)
+  -- 'fmap' 'distribute' . 'collect' f = 'getCompose' . 'collect' ('Compose' . f)
+  -- @
+
   collect     :: Functor f => (a -> g b) -> f a -> g (f b)
   collect f   = distribute . fmap f
 
   -- | The dual of 'Data.Traversable.sequence'
   --
-  -- @'distributeM' = 'fmap' 'unwrapMonad' . 'distribute' . 'WrapMonad'@
+  -- @
+  -- 'distributeM' = 'fmap' 'unwrapMonad' . 'distribute' . 'WrapMonad'
+  -- @
   distributeM :: Monad m => m (g a) -> g (m a)
   distributeM = fmap unwrapMonad . distribute . WrapMonad
 
   -- |
-  -- @'collectM' = 'distributeM' . 'liftM' f@
+  -- @
+  -- 'collectM' = 'distributeM' . 'liftM' f
+  -- @
   collectM    :: Monad m => (a -> g b) -> m a -> g (m b)
   collectM f  = distributeM . liftM f
 
 -- | The dual of 'Data.Traversable.traverse'
 --
--- @'cotraverse' f = 'fmap' f . 'distribute'@
-cotraverse :: (Functor f, Distributive g) => (f a -> b) -> f (g a) -> g b
+-- @
+-- 'cotraverse' f = 'fmap' f . 'distribute'
+-- @
+cotraverse :: (Distributive g, Functor f) => (f a -> b) -> f (g a) -> g b
 cotraverse f = fmap f . distribute
 
 -- | The dual of 'Data.Traversable.mapM'
 --
--- @'comapM' f = 'fmap' f . 'distributeM'@
-comapM :: (Monad m, Distributive g) => (m a -> b) -> m (g a) -> g b
+-- @
+-- 'comapM' f = 'fmap' f . 'distributeM'
+-- @
+comapM :: (Distributive g, Monad m) => (m a -> b) -> m (g a) -> g b
 comapM f = fmap f . distributeM
 
 instance Distributive Identity where
   collect f = Identity . fmap (runIdentity . f)
   distribute = Identity . fmap runIdentity
 
+#if __GLASGOW_HASKELL__ >= 707 || defined(MIN_VERSION_tagged)
 instance Distributive Proxy where
   collect _ _ = Proxy
   distribute _ = Proxy
+#endif
 
+#if defined(MIN_VERSION_tagged)
 instance Distributive (Tagged t) where
   collect f = Tagged . fmap (unTagged . f)
   distribute = Tagged . fmap unTagged
+#endif
 
 instance Distributive ((->)e) where
   distribute a e = fmap ($e) a
@@ -148,6 +177,24 @@
   collect f  = Monoid.Sum . fmap (Monoid.getSum . f)
   distribute = Monoid.Sum . fmap Monoid.getSum
 
+#if __GLASGOW_HASKELL__ >= 800 || defined(MIN_VERSION_semigroups)
+instance Distributive Semigroup.Min where
+  collect f  = Semigroup.Min . fmap (Semigroup.getMin . f)
+  distribute = Semigroup.Min . fmap Semigroup.getMin
+
+instance Distributive Semigroup.Max where
+  collect f  = Semigroup.Max . fmap (Semigroup.getMax . f)
+  distribute = Semigroup.Max . fmap Semigroup.getMax
+
+instance Distributive Semigroup.First where
+  collect f  = Semigroup.First . fmap (Semigroup.getFirst . f)
+  distribute = Semigroup.First . fmap Semigroup.getFirst
+
+instance Distributive Semigroup.Last where
+  collect f  = Semigroup.Last . fmap (Semigroup.getLast . f)
+  distribute = Semigroup.Last . fmap Semigroup.getLast
+#endif
+
 #if MIN_VERSION_base(4,4,0)
 instance Distributive Complex where
   distribute wc = fmap realP wc :+ fmap imagP wc where
@@ -155,4 +202,31 @@
     -- constraints on older versions of base
     realP (r :+ _) = r
     imagP (_ :+ i) = i
+#endif
+
+-- | 'fmapCollect' is a viable default definition for 'fmap' given
+-- a 'Distributive' instance defined in terms of 'collect'.
+fmapCollect :: Distributive f => (a -> b) -> f a -> f b
+fmapCollect f = runIdentity . collect (Identity . f)
+
+#if __GLASGOW_HASKELL__ >= 702
+instance Distributive U1 where
+  distribute _ = U1
+
+instance (Distributive a, Distributive b) => Distributive (a :*: b) where
+  distribute f = distribute (fmap fstP f) :*: distribute (fmap sndP f) where
+    fstP (l :*: _) = l
+    sndP (_ :*: r) = r
+
+instance (Distributive a, Distributive b) => Distributive (a :.: b) where
+  distribute = Comp1 . fmap distribute . distribute . fmap unComp1
+
+instance Distributive Par1 where
+  distribute = Par1 . fmap unPar1
+
+instance Distributive f => Distributive (Rec1 f) where
+  distribute = Rec1 . distribute . fmap unRec1
+
+instance Distributive f => Distributive (M1 i c f) where
+  distribute = M1 . distribute . fmap unM1
 #endif
