diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2011-2013 Edward Kmett
+Copyright 2011-2014 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.12.2
+version:       0.13
 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-2013 Edward A. Kmett
+copyright:     Copyright (C) 2011-2014 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.
@@ -31,6 +31,9 @@
   if !impl(hugs)
     other-extensions: DeriveDataTypeable
     cpp-options: -DLANGUAGE_DeriveDataTypeable
+
+  if impl(ghc >= 7.4)
+    cpp-options: -DLANGUAGE_DeriveGeneric
 
   if flag(base2)
     build-depends: base == 2.*
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
@@ -5,7 +5,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.List.NonEmpty
--- Copyright   :  (C) 2011-2013 Edward Kmett,
+-- Copyright   :  (C) 2011-2014 Edward Kmett,
 --                (C) 2010 Tony Morris, Oliver Taylor, Eelis van der Weegen
 -- License     :  BSD-style (see the file LICENSE)
 --
@@ -172,22 +172,6 @@
   b <$ ~(_ :| as)   = b   :| (b <$ as)
 #endif
 
-{-
-instance Extend NonEmpty where
-  extend f w@ ~(_ :| aas) = f w :| case aas of
-      []     -> []
-      (a:as) -> toList (extend f (a :| as))
-
-instance Comonad NonEmpty where
-  extract ~(a :| _) = a
-
-instance Apply NonEmpty where
-  (<.>) = ap
-
-instance Alt NonEmpty where
-  (a :| as) <!> ~(b :| bs) = a :| (as ++ b : bs)
--}
-
 instance Applicative NonEmpty where
   pure a = a :| []
   (<*>) = ap
@@ -201,12 +185,6 @@
 instance Traversable NonEmpty where
   traverse f ~(a :| as) = (:|) <$> f a <*> traverse f as
 
-{-
-instance Traversable1 NonEmpty where
-  traverse1 f (a :| []) = (:|[]) <$> f a
-  traverse1 f (a :| (b: bs)) = (\a' (b':| bs') -> a' :| b': bs') <$> f a <.> traverse1 f (b :| bs)
--}
-
 instance Foldable NonEmpty where
   foldr f z ~(a :| as) = f a (foldr f z as)
   foldl f z ~(a :| as) = foldl f (f z a) as
@@ -214,15 +192,6 @@
   foldMap f ~(a :| as) = f a `mappend` foldMap f as
   fold ~(m :| ms) = m `mappend` fold ms
 
-{-
-instance Foldable1 NonEmpty where
-  foldMap1 f (a :| []) = f a
-  foldMap1 f (a :| b : bs) = f a <> foldMap1 f (b :| bs)
-
-instance Semigroup (NonEmpty a) where
-  (<>) = (<!>)
--}
-
 -- | Extract the first element of the stream.
 head :: NonEmpty a -> a
 head ~(a :| _) = a
@@ -547,7 +516,7 @@
 nubBy :: (a -> a -> Bool) -> NonEmpty a -> NonEmpty a
 nubBy eq (a :| as) = a :| List.nubBy eq (List.filter (\b -> not (eq a b)) as)
 
--- | 'transpose' for NonEmtpy, behaves the same as 'Data.List.transpose'
+-- | 'transpose' for 'NonEmpty', behaves the same as 'Data.List.transpose'
 -- The rows/columns need not be the same length, in which case
 -- > transpose . transpose /= id
 transpose :: NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty a)
@@ -555,11 +524,11 @@
           . fromList . List.transpose . Foldable.toList
           . fmap Foldable.toList
 
--- | 'sortBy' for NonEmtpy, behaves the same as 'Data.List.sortBy'
+-- | 'sortBy' for 'NonEmpty', behaves the same as 'Data.List.sortBy'
 sortBy :: (a -> a -> Ordering) -> NonEmpty a -> NonEmpty a
 sortBy f = lift (List.sortBy f)
 
--- | 'sortOn' for NonEmtpy, behaves the same as:
+-- | 'sortOn' for 'NonEmpty', behaves the same as:
 --
 -- > sortBy . comparing
 sortOn :: Ord o => (a -> o) -> NonEmpty a -> NonEmpty a
diff --git a/src/Data/Semigroup.hs b/src/Data/Semigroup.hs
--- a/src/Data/Semigroup.hs
+++ b/src/Data/Semigroup.hs
@@ -2,6 +2,10 @@
 #ifdef LANGUAGE_DeriveDataTypeable
 {-# LANGUAGE DeriveDataTypeable #-}
 #endif
+#ifdef LANGUAGE_DeriveGeneric
+{-# LANGUAGE DeriveGeneric #-}
+#endif
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE DefaultSignatures #-}
 {-# LANGUAGE Trustworthy #-}
@@ -9,7 +13,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Semigroup
--- Copyright   :  (C) 2011-2013 Edward Kmett,
+-- Copyright   :  (C) 2011-2014 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
@@ -86,17 +90,24 @@
 #ifdef LANGUAGE_DeriveDataTypeable
 import Data.Data
 #endif
+#ifdef LANGUAGE_DeriveGeneric
+import GHC.Generics
+#endif
 
 infixr 6 <>
 
 class Semigroup a where
   -- | An associative operation.
   --
-  -- > (a <> b) <> c = a <> (b <> c)
+  -- @
+  -- (a '<>' b) '<>' c = a '<>' (b '<>' c)
+  -- @
   --
   -- If @a@ is also a 'Monoid' we further require
   --
-  -- > (<>) = mappend
+  -- @
+  -- ('<>') = 'mappend'
+  -- @
   (<>) :: a -> a -> a
 #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
   default (<>) :: Monoid a => a -> a -> a
@@ -114,12 +125,14 @@
 
   -- | Repeat a value (n + 1) times.
   --
-  -- > times1p n a = a <> a <> ... <> a  -- using <> n times
+  -- @
+  -- 'times1p' n a = a '<>' a '<>' ... '<>' a  -- using '<>' n times
+  -- @
   --
   -- The default definition uses peasant multiplication, exploiting associativity to only
   -- require /O(log n)/ uses of @\<\>@.
   --
-  -- See also 'times'.
+  -- See also 'timesN'.
 
   times1p :: Whole n => n -> a -> a
   times1p y0 x0 = f x0 (1 Prelude.+ y0)
@@ -224,7 +237,8 @@
   (a :| as) <> ~(b :| bs) = a :| (as ++ b : bs)
 
 newtype Min a = Min { getMin :: a } deriving
-  ( Eq, Ord, Bounded, Show, Read
+  ( Eq, Ord, Enum, Bounded, Show, Read
+  , Hashable
 #ifdef LANGUAGE_DeriveDataTypeable
   , Data, Typeable
 #endif
@@ -238,11 +252,38 @@
   mempty = maxBound
   mappend = (<>)
 
+instance Functor Min where
+  fmap f (Min x) = Min (f x)
+
+instance Foldable Min where
+  foldMap f (Min a) = f a
+
+instance Traversable Min where
+  traverse f (Min a) = Min <$> f a
+
+instance Applicative Min where
+  pure = Min
+  a <* _ = a
+  _ *> a = a
+  Min f <*> Min x = Min (f x)
+
+instance Monad Min where
+  return = Min
+  _ >> a = a
+  Min a >>= f = f a
+
+instance MonadFix Min where
+  mfix f = fix (f . getMin)
+
 newtype Max a = Max { getMax :: a } deriving
-  ( Eq, Ord, Bounded, Show, Read
+  ( Eq, Ord, Enum, Bounded, Show, Read
+  , Hashable
 #ifdef LANGUAGE_DeriveDataTypeable
   , Data, Typeable
 #endif
+#ifdef LANGUAGE_DeriveGeneric
+  , Generic
+#endif
   )
 
 instance Ord a => Semigroup (Max a) where
@@ -253,31 +294,109 @@
   mempty = minBound
   mappend = (<>)
 
+instance Functor Max where
+  fmap f (Max x) = Max (f x)
+
+instance Foldable Max where
+  foldMap f (Max a) = f a
+
+instance Traversable Max where
+  traverse f (Max a) = Max <$> f a
+
+instance Applicative Max where
+  pure = Max
+  a <* _ = a
+  _ *> a = a
+  Max f <*> Max x = Max (f x)
+
+instance Monad Max where
+  return = Max
+  _ >> a = a
+  Max a >>= f = f a
+
+instance MonadFix Max where
+  mfix f = fix (f . getMax)
+
 -- | Use @'Option' ('First' a)@ to get the behavior of 'Data.Monoid.First' from @Data.Monoid@.
 newtype First a = First { getFirst :: a } deriving
-  ( Eq, Ord, Bounded, Show, Read
+  ( Eq, Ord, Enum, Bounded, Show, Read
+  , Hashable
 #ifdef LANGUAGE_DeriveDataTypeable
   , Data
   , Typeable
 #endif
+#ifdef LANGUAGE_DeriveGeneric
+  , Generic
+#endif
   )
 
 instance Semigroup (First a) where
   a <> _ = a
   times1p _ a = a
 
+instance Functor First where
+  fmap f (First x) = First (f x)
+
+instance Foldable First where
+  foldMap f (First a) = f a
+
+instance Traversable First where
+  traverse f (First a) = First <$> f a
+
+instance Applicative First where
+  pure x = First x
+  a <* _ = a
+  _ *> a = a
+  First f <*> First x = First (f x)
+
+instance Monad First where
+  return = First
+  _ >> a = a
+  First a >>= f = f a
+
+instance MonadFix First where
+  mfix f = fix (f . getFirst)
+
 -- | Use @'Option' ('Last' a)@ to get the behavior of 'Data.Monoid.Last' from @Data.Monoid@
 newtype Last a = Last { getLast :: a } deriving
-  ( Eq, Ord, Bounded, Show, Read
+  ( Eq, Ord, Enum, Bounded, Show, Read
+  , Hashable
 #ifdef LANGUAGE_DeriveDataTypeable
   , Data, Typeable
 #endif
+#ifdef LANGUAGE_DeriveGeneric
+  , Generic
+#endif
   )
 
 instance Semigroup (Last a) where
   _ <> b = b
   times1p _ a = a
 
+instance Functor Last where
+  fmap f (Last x) = Last (f x)
+  a <$ _ = Last a
+
+instance Foldable Last where
+  foldMap f (Last a) = f a
+
+instance Traversable Last where
+  traverse f (Last a) = Last <$> f a
+
+instance Applicative Last where
+  pure = Last
+  a <* _ = a
+  _ *> a = a
+  Last f <*> Last x = Last (f x)
+
+instance Monad Last where
+  return = Last
+  _ >> a = a
+  Last a >>= f = f a
+
+instance MonadFix Last where
+  mfix f = fix (f . getLast)
+
 -- (==)/XNOR on Bool forms a 'Semigroup', but has no good name
 
 #ifndef BASE2
@@ -304,10 +423,14 @@
 -- | Provide a Semigroup for an arbitrary Monoid.
 newtype WrappedMonoid m = WrapMonoid
   { unwrapMonoid :: m } deriving
-  ( Eq, Ord, Bounded, Show, Read
+  ( Eq, Ord, Enum, Bounded, Show, Read
+  , Hashable
 #ifdef LANGUAGE_DeriveDataTypeable
   , Data, Typeable
 #endif
+#ifdef LANGUAGE_DeriveGeneric
+  , Generic
+#endif
   )
 
 instance Monoid m => Semigroup (WrappedMonoid m) where
@@ -319,7 +442,7 @@
 
 -- | Repeat a value @n@ times.
 --
--- > times n a = a <> a <> ... <> a  -- using <> (n-1) times
+-- > timesN n a = a <> a <> ... <> a  -- using <> (n-1) times
 --
 -- Implemented using 'times1p'.
 timesN :: (Whole n, Monoid a) => n -> a -> a
@@ -328,14 +451,20 @@
 {-# INLINE timesN #-}
 
 
--- | Option is effectively 'Maybe' with a better instance of 'Monoid', built off of an underlying 'Semigroup'
--- instead of an underlying 'Monoid'. Ideally, this type would not exist at all and we would just fix the 'Monoid' intance of 'Maybe'
+-- | 'Option' is effectively 'Maybe' with a better instance of 'Monoid', built off of an underlying 'Semigroup'
+-- instead of an underlying 'Monoid'.
+--
+-- Ideally, this type would not exist at all and we would just fix the 'Monoid' instance of 'Maybe'
 newtype Option a = Option
   { getOption :: Maybe a } deriving
   ( Eq, Ord, Show, Read
+  , Hashable
 #ifdef LANGUAGE_DeriveDataTypeable
   , Data, Typeable
 #endif
+#ifdef LANGUAGE_DeriveGeneric
+  , Generic
+#endif
   )
 
 instance Functor Option where
@@ -385,7 +514,7 @@
   mempty = Option Nothing
   Option a `mappend` Option b = Option (a <> b)
 
--- | This lets you use a difference list of a Semigroup as a Monoid.
+-- | This lets you use a difference list of a 'Semigroup' as a 'Monoid'.
 diff :: Semigroup m => m -> Endo m
 diff = Endo . (<>)
 
