diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,21 +21,30 @@
 
 matrix:
   include:
-    - env: CABALVER=1.16 GHCVER=7.0.4
+    - env: CABALVER=1.18 GHCVER=7.0.4
       compiler: ": #GHC 7.0.4"
-      addons: {apt: {packages: [cabal-install-1.16,ghc-7.0.4], sources: [hvr-ghc]}}
-    - env: CABALVER=1.16 GHCVER=7.4.2
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.0.4], sources: [hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.2.2
+      compiler: ": #GHC 7.2.2"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.2.2], sources: [hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.4.2
       compiler: ": #GHC 7.4.2"
-      addons: {apt: {packages: [cabal-install-1.16,ghc-7.4.2], sources: [hvr-ghc]}}
-    - env: CABALVER=1.16 GHCVER=7.6.3
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.4.2], sources: [hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.6.3
       compiler: ": #GHC 7.6.3"
-      addons: {apt: {packages: [cabal-install-1.16,ghc-7.6.3], sources: [hvr-ghc]}}
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.6.3], sources: [hvr-ghc]}}
     - env: CABALVER=1.18 GHCVER=7.8.4
       compiler: ": #GHC 7.8.4"
       addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: [hvr-ghc]}}
-    - env: CABALVER=1.22 GHCVER=7.10.2
-      compiler: ": #GHC 7.10.2"
-      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2], sources: [hvr-ghc]}}
+    - env: CABALVER=1.22 GHCVER=7.10.3
+      compiler: ": #GHC 7.10.3"
+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=8.0.2
+      compiler: ": #GHC 8.0.2"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2], sources: [hvr-ghc]}}
+    - env: CABALVER=2.0 GHCVER=8.2.1
+      compiler: ": #GHC 8.2.1"
+      addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.1], sources: [hvr-ghc]}}
     - env: CABALVER=head GHCVER=head
       compiler: ": #GHC head"
       addons: {apt: {packages: [cabal-install-head,ghc-head], sources: [hvr-ghc]}}
@@ -71,9 +80,9 @@
      echo "cabal build-cache MISS";
      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;
+     cabal install -j --only-dependencies --enable-tests --enable-benchmarks;
    fi
- 
+
 # snapshot package-db on cache miss
  - if [ ! -d $HOME/.cabsnap ];
    then
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,11 @@
+0.18.3
+------
+* Add `Semigroup` instance for `IO`, as well as for `Event` and `Lifetime` from
+  `GHC.Event`
+* Add `Eq1`, `Ord1`, `Read1`, and `Show1` instances for `NonEmpty`
+* Define `Generic` and `Generic1` instances back to GHC 7.2, and expose the
+  `Data.Semigroup.Generic` module on GHC 7.2
+
 0.18.2
 ------
 * Depend on the `bytestring-builder` package to ensure `Semigroup` instances for bytestring `Builder` and `ShortByteString` are always defined
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.18.2
+version:       0.18.3
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
@@ -50,17 +50,17 @@
 
 flag bytestring-builder
   description:
-    You can disable the use of the `bytestring-builder` package using `-f-bytestring-builder`.
+    Decides whether to use an older version of bytestring along with bytestring-builder or just a newer version of bytestring.
     .
-    Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.
-  default: True
+    This flag normally toggles automatically but you can use `-fbytestring-builder` or `-f-bytestring-builder` to explicitly change it.
+  default: False
   manual: False
 
 flag containers
   description:
     You can disable the use of the `containers` package using `-f-containers`.
     .
-    Disabing this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.
+    Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.
   default: True
   manual: True
 
@@ -68,7 +68,7 @@
   description:
     You can disable the use of the `deepseq` package using `-f-deepseq`.
     .
-    Disabing this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.
+    Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.
   default: True
   manual: True
 
@@ -90,7 +90,7 @@
 
 flag transformers
   description:
-    You can disable the use of the `transformers` package using `-f-transformers`.
+    You can disable the use of the `transformers` and `transformers-compat` packages using `-f-transformers`.
     .
     Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.
   default: True
@@ -111,7 +111,7 @@
 
   build-depends: base >= 2 && < 5
 
-  if impl(ghc >= 7.4)
+  if impl(ghc >= 7.2)
     exposed-modules:
       Data.Semigroup.Generic
 
@@ -127,7 +127,7 @@
     if impl(ghc < 7.10)
       build-depends: nats >= 0.1 && < 2
 
-    if impl(ghc >= 7.4 && < 7.5)
+    if impl(ghc >= 7.2 && < 7.5)
       build-depends: ghc-prim
 
     if flag(binary)
@@ -159,4 +159,5 @@
       build-depends: unordered-containers >= 0.2  && < 0.3
 
     if flag(transformers)
-      build-depends: transformers >= 0.2 && < 0.6
+      build-depends: transformers        >= 0.2 && < 0.6
+                   , transformers-compat >= 0.5 && < 1
diff --git a/src-ghc7/Data/List/NonEmpty.hs b/src-ghc7/Data/List/NonEmpty.hs
--- a/src-ghc7/Data/List/NonEmpty.hs
+++ b/src-ghc7/Data/List/NonEmpty.hs
@@ -1,7 +1,8 @@
 {-# LANGUAGE CPP #-}
 
 #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-#if defined(MIN_VERSION_hashable) || __GLASGOW_HASKELL__ >= 708
+#if defined(MIN_VERSION_hashable) || __GLASGOW_HASKELL__ == 702 \
+                                  || __GLASGOW_HASKELL__ >= 708
 {-# LANGUAGE Trustworthy #-}
 #else
 {-# LANGUAGE Safe #-}
@@ -13,13 +14,12 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 #endif
 
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
 #define LANGUAGE_DeriveGeneric
 {-# LANGUAGE DeriveGeneric #-}
-#endif
-
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
+{-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
 #endif
 
 #ifndef MIN_VERSION_base
@@ -136,7 +136,7 @@
 #endif
 
 #ifdef LANGUAGE_DeriveDataTypeable
-import Data.Data
+import Data.Data hiding (Infix)
 #endif
 
 #if MIN_VERSION_base(4,8,0)
@@ -153,6 +153,10 @@
 import Data.Hashable
 #endif
 
+#ifdef MIN_VERSION_transformers
+import Data.Functor.Classes (Eq1(..), Ord1(..), Read1(..), Show1(..))
+#endif
+
 import qualified Data.List as List
 import Data.Ord (comparing)
 
@@ -198,6 +202,28 @@
   toList = toList
 #endif
 
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 706
+instance Generic1 NonEmpty where
+  type Rep1 NonEmpty
+    = D1 D1NonEmpty
+        (C1 C1_0NonEmpty
+             (S1 NoSelector Par1
+          :*: S1 NoSelector (Rec1 [])))
+  from1 (h :| t) = M1 (M1 (M1 (Par1 h) :*: M1 (Rec1 t)))
+  to1 (M1 (M1 (M1 h :*: M1 t))) = unPar1 h :| unRec1 t
+
+instance Datatype D1NonEmpty where
+  datatypeName _ = "NonEmpty"
+  moduleName   _ = "Data.List.NonEmpty"
+
+instance Constructor C1_0NonEmpty where
+  conName   _ = ":|"
+  conFixity _ = Infix RightAssociative 5
+
+data D1NonEmpty
+data C1_0NonEmpty
+#endif
+
 #ifdef MIN_VERSION_deepseq
 instance NFData a => NFData (NonEmpty a) where
   rnf (x :| xs) = rnf x `seq` rnf xs
@@ -214,6 +240,44 @@
   munzip   = unzip
 #endif
 
+#ifdef MIN_VERSION_transformers
+# if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)
+instance Eq1 NonEmpty where
+  liftEq eq (a :| as) (b :| bs) = eq a b && liftEq eq as bs
+
+instance Ord1 NonEmpty where
+  liftCompare cmp (a :| as) (b :| bs) = cmp a b `mappend` liftCompare cmp as bs
+
+instance Read1 NonEmpty where
+  liftReadsPrec rdP rdL p s = readParen (p > 5) (\s' -> do
+    (a, s'') <- rdP 6 s'
+    (":|", s''') <- lex s''
+    (as, s'''') <- rdL s'''
+    return (a :| as, s'''')) s
+
+instance Show1 NonEmpty where
+  liftShowsPrec shwP shwL p (a :| as) = showParen (p > 5) $
+    shwP 6 a . showString " :| " . shwL as
+# else
+instance Eq1 NonEmpty where
+  eq1 (a :| as) (b :| bs) = a == b && as == bs
+
+instance Ord1 NonEmpty where
+  compare1 (a :| as) (b :| bs) = compare a b `mappend` compare as bs
+
+instance Read1 NonEmpty where
+  readsPrec1 p s = readParen (p > 5) (\s' -> do
+    (a, s'') <- readsPrec 6 s'
+    (":|", s''') <- lex s''
+    (as, s'''') <- readList s'''
+    return (a :| as, s'''')) s
+
+instance Show1 NonEmpty where
+  showsPrec1 p (a :| as) = showParen (p > 5) $
+    showsPrec 6 a . showString " :| " . showList as
+# endif
+#endif
+
 length :: NonEmpty a -> Int
 length (_ :| xs) = 1 + Prelude.length xs
 {-# INLINE length #-}
@@ -277,6 +341,10 @@
   foldl1 f ~(a :| as) = foldl f a as
   foldMap f ~(a :| as) = f a `mappend` foldMap f as
   fold ~(m :| ms) = m `mappend` fold ms
+#if MIN_VERSION_base(4,8,0)
+  length = length
+  toList = toList
+#endif
 
 -- | Extract the first element of the stream.
 head :: NonEmpty a -> a
@@ -581,7 +649,7 @@
 {-# INLINE unzip #-}
 
 -- | The 'nub' function removes duplicate elements from a list. In
--- particular, it keeps only the first occurence of each element.
+-- particular, it keeps only the first occurrence of each element.
 -- (The name 'nub' means \'essence\'.)
 -- It is a special case of 'nubBy', which allows the programmer to
 -- supply their own inequality test.
@@ -599,8 +667,8 @@
 -- > transpose . transpose /= id
 transpose :: NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty a)
 transpose = fmap fromList
-          . fromList . List.transpose . Foldable.toList
-          . fmap Foldable.toList
+          . fromList . List.transpose . toList
+          . fmap toList
 
 -- | 'sortBy' for 'NonEmpty', behaves the same as 'Data.List.sortBy'
 sortBy :: (a -> a -> Ordering) -> NonEmpty a -> NonEmpty a
diff --git a/src-ghc7/Data/Semigroup.hs b/src-ghc7/Data/Semigroup.hs
--- a/src-ghc7/Data/Semigroup.hs
+++ b/src-ghc7/Data/Semigroup.hs
@@ -8,18 +8,21 @@
 #if __GLASGOW_HASKELL__ >= 702
 #define LANGUAGE_DefaultSignatures
 {-# LANGUAGE DefaultSignatures #-}
-#if (defined(MIN_VERSION_hashable)) || __GLASGOW_HASKELL__ >= 708
+#if (defined(MIN_VERSION_hashable)) || __GLASGOW_HASKELL__ == 702 \
+                                    || __GLASGOW_HASKELL__ >= 708
 {-# LANGUAGE Trustworthy #-}
 #else
 {-# LANGUAGE Safe #-}
 #endif
 #endif
 
-#if __GLASGOW_HASKELL__ >= 704
+#if __GLASGOW_HASKELL__ >= 702
 #define LANGUAGE_DeriveGeneric
 {-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
 #endif
 
 #if __GLASGOW_HASKELL__ >= 706
@@ -113,6 +116,9 @@
 import Control.Monad.Fix
 import qualified Data.Monoid as Monoid
 import Data.List.NonEmpty
+#if MIN_VERSION_base(4,4,0) && !defined(mingw32_HOST_OS) && !defined(ghcjs_HOST_OS)
+import GHC.Event
+#endif
 
 #ifdef MIN_VERSION_deepseq
 import Control.DeepSeq (NFData(..))
@@ -511,6 +517,28 @@
   signum (Min a) = Min (signum a)
   fromInteger    = Min . fromInteger
 
+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 706
+instance Generic1 Min where
+  type Rep1 Min = D1 D1Min (C1 C1_0Min (S1 S1_0_0Min Par1))
+  from1 (Min x) = M1 (M1 (M1 (Par1 x)))
+  to1 (M1 (M1 (M1 x))) = Min (unPar1 x)
+
+instance Datatype D1Min where
+  datatypeName _ = "Min"
+  moduleName   _ = "Data.Semigroup"
+
+instance Constructor C1_0Min where
+  conName     _ = "Min"
+  conIsRecord _ = True
+
+instance Selector S1_0_0Min where
+  selName _ = "getMin"
+
+data D1Min
+data C1_0Min
+data S1_0_0Min
+#endif
+
 newtype Max a = Max { getMax :: a } deriving
   ( Eq, Ord, Show, Read
 #ifdef LANGUAGE_DeriveDataTypeable
@@ -596,7 +624,28 @@
   signum (Max a) = Max (signum a)
   fromInteger    = Max . fromInteger
 
+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 706
+instance Generic1 Max where
+  type Rep1 Max = D1 D1Max (C1 C1_0Max (S1 S1_0_0Max Par1))
+  from1 (Max x) = M1 (M1 (M1 (Par1 x)))
+  to1 (M1 (M1 (M1 x))) = Max (unPar1 x)
 
+instance Datatype D1Max where
+  datatypeName _ = "Max"
+  moduleName   _ = "Data.Semigroup"
+
+instance Constructor C1_0Max where
+  conName     _ = "Max"
+  conIsRecord _ = True
+
+instance Selector S1_0_0Max where
+  selName _ = "getMax"
+
+data D1Max
+data C1_0Max
+data S1_0_0Max
+#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
@@ -655,6 +704,27 @@
   bimap f g (Arg a b) = Arg (f a) (g b)
 #endif
 
+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 706
+instance Generic1 (Arg a) where
+  type Rep1 (Arg a)
+    = D1 D1Arg
+        (C1 C1_0Arg
+             (S1 NoSelector (Rec0 a)
+          :*: S1 NoSelector Par1))
+  from1 (Arg a b) = M1 (M1 (M1 (K1 a) :*: M1 (Par1 b)))
+  to1 (M1 (M1 (M1 a :*: M1 b))) = Arg (unK1 a) (unPar1 b)
+
+instance Datatype D1Arg where
+  datatypeName _ = "Arg"
+  moduleName   _ = "Data.Semigroup"
+
+instance Constructor C1_0Arg where
+  conName _ = "Arg"
+
+data D1Arg
+data C1_0Arg
+#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
@@ -725,6 +795,28 @@
   rnf (First a) = rnf a
 #endif
 
+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 706
+instance Generic1 First where
+  type Rep1 First = D1 D1First (C1 C1_0First (S1 S1_0_0First Par1))
+  from1 (First x) = M1 (M1 (M1 (Par1 x)))
+  to1 (M1 (M1 (M1 x))) = First (unPar1 x)
+
+instance Datatype D1First where
+  datatypeName _ = "First"
+  moduleName   _ = "Data.Semigroup"
+
+instance Constructor C1_0First where
+  conName     _ = "First"
+  conIsRecord _ = True
+
+instance Selector S1_0_0First where
+  selName _ = "getFirst"
+
+data D1First
+data C1_0First
+data S1_0_0First
+#endif
+
 -- | Use @'Option' ('Last' a)@ to get the behavior of 'Data.Monoid.Last' from @Data.Monoid@
 newtype Last a = Last { getLast :: a } deriving
   ( Eq, Ord, Show, Read
@@ -795,6 +887,28 @@
   rnf (Last a) = rnf a
 #endif
 
+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 706
+instance Generic1 Last where
+  type Rep1 Last = D1 D1Last (C1 C1_0Last (S1 S1_0_0Last Par1))
+  from1 (Last x) = M1 (M1 (M1 (Par1 x)))
+  to1 (M1 (M1 (M1 x))) = Last (unPar1 x)
+
+instance Datatype D1Last where
+  datatypeName _ = "Last"
+  moduleName   _ = "Data.Semigroup"
+
+instance Constructor C1_0Last where
+  conName     _ = "Last"
+  conIsRecord _ = True
+
+instance Selector S1_0_0Last where
+  selName _ = "getLast"
+
+data D1Last
+data C1_0Last
+data S1_0_0Last
+#endif
+
 -- (==)/XNOR on Bool forms a 'Semigroup', but has no good name
 
 #ifdef MIN_VERSION_binary
@@ -897,6 +1011,28 @@
   rnf (WrapMonoid a) = rnf a
 #endif
 
+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 706
+instance Generic1 WrappedMonoid where
+  type Rep1 WrappedMonoid = D1 D1WrappedMonoid (C1 C1_0WrappedMonoid (S1 S1_0_0WrappedMonoid Par1))
+  from1 (WrapMonoid x) = M1 (M1 (M1 (Par1 x)))
+  to1 (M1 (M1 (M1 x))) = WrapMonoid (unPar1 x)
+
+instance Datatype D1WrappedMonoid where
+  datatypeName _ = "WrappedMonoid"
+  moduleName   _ = "Data.Semigroup"
+
+instance Constructor C1_0WrappedMonoid where
+  conName     _ = "WrapMonoid"
+  conIsRecord _ = True
+
+instance Selector S1_0_0WrappedMonoid where
+  selName _ = "unwrapMonoid"
+
+data D1WrappedMonoid
+data C1_0WrappedMonoid
+data S1_0_0WrappedMonoid
+#endif
+
 -- | Repeat a value @n@ times.
 --
 -- > mtimesDefault n a = a <> a <> ... <> a  -- using <> (n-1) times
@@ -999,6 +1135,28 @@
   mempty = Option Nothing
   mappend = (<>)
 
+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 706
+instance Generic1 Option where
+  type Rep1 Option = D1 D1Option (C1 C1_0Option (S1 S1_0_0Option (Rec1 Maybe)))
+  from1 (Option x) = M1 (M1 (M1 (Rec1 x)))
+  to1 (M1 (M1 (M1 x))) = Option (unRec1 x)
+
+instance Datatype D1Option where
+  datatypeName _ = "Option"
+  moduleName   _ = "Data.Semigroup"
+
+instance Constructor C1_0Option where
+  conName     _ = "Option"
+  conIsRecord _ = True
+
+instance Selector S1_0_0Option where
+  selName _ = "getOption"
+
+data D1Option
+data C1_0Option
+data S1_0_0Option
+#endif
+
 -- | This lets you use a difference list of a 'Semigroup' as a 'Monoid'.
 diff :: Semigroup m => m -> Endo m
 diff = Endo . (<>)
@@ -1049,4 +1207,21 @@
   Tagged a <> Tagged b = Tagged (a <> b)
 # endif
   stimes n (Tagged a) = Tagged (stimes n a)
+#endif
+
+instance Semigroup a => Semigroup (IO a) where
+    (<>) = liftA2 (<>)
+
+#if !defined(mingw32_HOST_OS) && !defined(ghcjs_HOST_OS)
+# if MIN_VERSION_base(4,4,0)
+instance Semigroup Event where
+    (<>) = mappend
+    stimes = stimesMonoid
+# endif
+
+# if MIN_VERSION_base(4,8,1)
+instance Semigroup Lifetime where
+    (<>) = mappend
+    stimes = stimesMonoid
+# endif
 #endif
diff --git a/src/Data/Semigroup/Generic.hs b/src/Data/Semigroup/Generic.hs
--- a/src/Data/Semigroup/Generic.hs
+++ b/src/Data/Semigroup/Generic.hs
@@ -1,6 +1,11 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE FlexibleContexts #-}
+#if __GLASGOW_HASKELL__ >= 704
 {-# LANGUAGE Safe #-}
+#else
+{-# LANGUAGE Trustworthy #-}
+#endif
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Semigroup.Generic
