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.15.3
+version:       0.15.4
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
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
@@ -131,7 +131,11 @@
 import Data.Data
 #endif
 
+#if MIN_VERSION_base(4,8,0)
+import Data.Foldable hiding (toList, length)
+#else
 import Data.Foldable hiding (toList)
+#endif
 import qualified Data.Foldable as Foldable
 
 #ifdef MIN_VERSION_hashable
diff --git a/src/Data/Semigroup.hs b/src/Data/Semigroup.hs
--- a/src/Data/Semigroup.hs
+++ b/src/Data/Semigroup.hs
@@ -20,6 +20,12 @@
 {-# LANGUAGE DeriveGeneric #-}
 #endif
 
+
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
+#define USE_COERCE
+{-# LANGUAGE ScopedTypeVariables #-}
+#endif
+
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Semigroup
@@ -71,7 +77,7 @@
   ) where
 
 import Prelude hiding (foldr1)
-import Data.Monoid (Monoid(..),Dual(..),Endo(..),All(..),Any(..),Sum(..),Product(..),Endo(..))
+import Data.Monoid (Monoid(..),Dual(..),Endo(..),All(..),Any(..),Sum(..),Product(..))
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
@@ -120,6 +126,10 @@
 import GHC.Generics
 #endif
 
+#ifdef USE_COERCE
+import Data.Coerce
+#endif
+
 infixr 6 <>
 
 class Semigroup a where
@@ -228,24 +238,48 @@
   times1p n (Dual a) = Dual (times1p n a)
 
 instance Semigroup (Endo a) where
+#ifdef USE_COERCE
+  (<>) = coerce ((.) :: (a -> a) -> (a -> a) -> (a -> a))
+#else
   Endo f <> Endo g = Endo (f . g)
+#endif
 
 instance Semigroup All where
+#ifdef USE_COERCE
+  (<>) = coerce (&&)
+#else
   All a <> All b = All (a && b)
+#endif
   times1p _ a = a
 
 instance Semigroup Any where
+#ifdef USE_COERCE
+  (<>) = coerce (||)
+#else
   Any a <> Any b = Any (a || b)
+#endif
   times1p _ a = a
 
 instance Num a => Semigroup (Sum a) where
+#ifdef USE_COERCE
+  (<>) = coerce ((+) :: a -> a -> a)
+#else
   Sum a <> Sum b = Sum (a + b)
+#endif
 
 instance Num a => Semigroup (Product a) where
+#ifdef USE_COERCE
+  (<>) = coerce ((*) :: a -> a -> a)
+#else
   Product a <> Product b = Product (a * b)
+#endif
 
 instance Semigroup a => Semigroup (Const a b) where
+#ifdef USE_COERCE
+  (<>) = coerce ((<>) :: a -> a -> a)
+#else
   Const a <> Const b = Const (a <> b)
+#endif
 
 #if MIN_VERSION_base(3,0,0)
 instance Semigroup (Monoid.First a) where
@@ -296,7 +330,11 @@
 #endif
 
 instance Ord a => Semigroup (Min a) where
+#ifdef USE_COERCE
+  (<>) = coerce (min :: a -> a -> a)
+#else
   Min a <> Min b = Min (a `min` b)
+#endif
   times1p _ a = a
 
 instance (Ord a, Bounded a) => Monoid (Min a) where
@@ -365,7 +403,11 @@
 #endif
 
 instance Ord a => Semigroup (Max a) where
+#ifdef USE_COERCE
+  (<>) = coerce (max :: a -> a -> a)
+#else
   Max a <> Max b = Max (a `max` b)
+#endif
   times1p _ a = a
 
 instance (Ord a, Bounded a) => Monoid (Max a) where
@@ -583,11 +625,15 @@
 #endif
 
 instance Monoid m => Semigroup (WrappedMonoid m) where
+#ifdef USE_COERCE
+  (<>) = coerce (mappend :: m -> m -> m)
+#else
   WrapMonoid a <> WrapMonoid b = WrapMonoid (a `mappend` b)
+#endif
 
 instance Monoid m => Monoid (WrappedMonoid m) where
   mempty = WrapMonoid mempty
-  WrapMonoid a `mappend` WrapMonoid b = WrapMonoid (a `mappend` b)
+  mappend = (<>)
 
 instance Bounded a => Bounded (WrappedMonoid a) where
   minBound = WrapMonoid minBound
@@ -689,11 +735,15 @@
 option n j (Option m) = maybe n j m
 
 instance Semigroup a => Semigroup (Option a) where
+#ifdef USE_COERCE
+  (<>) = coerce ((<>) :: Maybe a -> Maybe a -> Maybe a)
+#else
   Option a <> Option b = Option (a <> b)
+#endif
 
 instance Semigroup a => Monoid (Option a) where
   mempty = Option Nothing
-  Option a `mappend` Option b = Option (a <> b)
+  mappend = (<>)
 
 -- | This lets you use a difference list of a 'Semigroup' as a 'Monoid'.
 diff :: Semigroup m => m -> Endo m
