diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,8 @@
+4.12.4
+------
+* Removed a number of spurious class constraints.
+* Support GHC 8
+
 4.12.3
 ------
 * Support `comonad` 5
diff --git a/free.cabal b/free.cabal
--- a/free.cabal
+++ b/free.cabal
@@ -1,6 +1,6 @@
 name:          free
 category:      Control, Monads
-version:       4.12.3
+version:       4.12.4
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
diff --git a/src/Control/Alternative/Free.hs b/src/Control/Alternative/Free.hs
--- a/src/Control/Alternative/Free.hs
+++ b/src/Control/Alternative/Free.hs
@@ -69,7 +69,7 @@
 
   (Alt xs) <*> ys = Alt (xs >>= alternatives . (`ap'` ys))
     where
-      ap' :: (Functor f) => AltF f (a -> b) -> Alt f a -> Alt f b
+      ap' :: AltF f (a -> b) -> Alt f a -> Alt f b
 
       Pure f `ap'` u      = fmap f u
       (u `Ap` f) `ap'` v  = Alt [u `Ap` (flip <$> f) <*> v]
diff --git a/src/Control/Comonad/Cofree/Class.hs b/src/Control/Comonad/Cofree/Class.hs
--- a/src/Control/Comonad/Cofree/Class.hs
+++ b/src/Control/Comonad/Cofree/Class.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -24,7 +25,9 @@
 import Control.Comonad.Trans.Identity
 import Data.List.NonEmpty
 import Data.Tree
-import Data.Semigroup
+#if __GLASGOW_HASKELL__ < 710
+import Data.Monoid
+#endif
 
 -- | Allows you to peel a layer off a cofree comonad.
 class (Functor f, Comonad w) => ComonadCofree f w | w -> f where
@@ -50,5 +53,5 @@
 instance ComonadCofree f w => ComonadCofree f (StoreT s w) where
   unwrap (StoreT wsa s) = flip StoreT s <$> unwrap wsa
 
-instance (ComonadCofree f w, Semigroup m, Monoid m) => ComonadCofree f (TracedT m w) where
+instance (ComonadCofree f w, Monoid m) => ComonadCofree f (TracedT m w) where
   unwrap (TracedT wma) = TracedT <$> unwrap wma
diff --git a/src/Control/Comonad/Trans/Cofree.hs b/src/Control/Comonad/Trans/Cofree.hs
--- a/src/Control/Comonad/Trans/Cofree.hs
+++ b/src/Control/Comonad/Trans/Cofree.hs
@@ -140,7 +140,7 @@
 instance (Traversable f, Traversable w) => Traversable (CofreeT f w) where
   traverse f = fmap CofreeT . traverse (bitraverse f (traverse f)) . runCofreeT
 
-instance Functor f => ComonadTrans (CofreeT f) where
+instance ComonadTrans (CofreeT f) where
   lower = fmap headF . runCofreeT
 
 instance (Functor f, Comonad w) => ComonadCofree f (CofreeT f w) where
diff --git a/src/Control/Monad/Free.hs b/src/Control/Monad/Free.hs
--- a/src/Control/Monad/Free.hs
+++ b/src/Control/Monad/Free.hs
@@ -320,7 +320,7 @@
 hoistFree f (Free as) = Free (hoistFree f <$> f as)
 
 -- | The very definition of a free monad is that given a natural transformation you get a monad homomorphism.
-foldFree :: (Functor m, Monad m) => (forall x . f x -> m x) -> Free f a -> m a
+foldFree :: Monad m => (forall x . f x -> m x) -> Free f a -> m a
 foldFree _ (Pure a)  = return a
 foldFree f (Free as) = f as >>= foldFree f
 
diff --git a/src/Control/Monad/Free/Church.hs b/src/Control/Monad/Free/Church.hs
--- a/src/Control/Monad/Free/Church.hs
+++ b/src/Control/Monad/Free/Church.hs
@@ -89,11 +89,11 @@
 newtype F f a = F { runF :: forall r. (a -> r) -> (f r -> r) -> r }
 
 -- | Tear down a 'Free' 'Monad' using iteration.
-iter :: Functor f => (f a -> a) -> F f a -> a
+iter :: (f a -> a) -> F f a -> a
 iter phi xs = runF xs id phi
 
 -- | Like iter for monadic values.
-iterM :: (Monad m, Functor f) => (f (m a) -> m a) -> F f a -> m a
+iterM :: Monad m => (f (m a) -> m a) -> F f a -> m a
 iterM phi xs = runF xs return phi
 
 instance Functor (F f) where
@@ -123,7 +123,7 @@
     a = f (impure a)
     impure (F x) = x id (error "MonadFix (F f): wrap")
 
-instance (Foldable f, Functor f) => Foldable (F f) where
+instance Foldable f => Foldable (F f) where
     foldr f r xs = runF xs f (foldr (.) id) r
     {-# INLINE foldr #-}
 
diff --git a/src/Control/Monad/Free/TH.hs b/src/Control/Monad/Free/TH.hs
--- a/src/Control/Monad/Free/TH.hs
+++ b/src/Control/Monad/Free/TH.hs
@@ -189,6 +189,7 @@
     RecC    cName fields -> liftCon' typeSig ts cx f n ns cName $ map (\(_, _, ty) -> ty) fields
     InfixC  (_,t1) cName (_,t2) -> liftCon' typeSig ts cx f n ns cName [t1, t2]
     ForallC ts' cx' con' -> liftCon typeSig (ts ++ ts') (cx ++ cx') f n ns con'
+    _ -> fail "Unsupported constructor type"
 
 -- | Provide free monadic actions for a type declaration.
 liftDec :: Bool             -- ^ Include type signature?
@@ -217,6 +218,7 @@
 constructorName (RecC     name _)   = name
 constructorName (InfixC   _ name _) = name
 constructorName (ForallC  _ _ c)    = constructorName c
+constructorName _ = error "Unsupported constructor type"
 
 -- | Generate monadic actions for a data type.
 genFree :: Bool         -- ^ Include type signature?
diff --git a/src/Control/Monad/Trans/Free.hs b/src/Control/Monad/Trans/Free.hs
--- a/src/Control/Monad/Trans/Free.hs
+++ b/src/Control/Monad/Trans/Free.hs
@@ -431,7 +431,11 @@
 -- @
 -- 'intercalateT' f ≡ 'retractT' . 'intersperseT' f
 -- @
+#if __GLASGOW_HASKELL__ < 710
 intercalateT :: (Monad m, MonadTrans t, Monad (t m), Functor (t m)) => t m a -> FreeT (t m) m b -> t m b
+#else
+intercalateT :: (Monad m, MonadTrans t, Monad (t m)) => t m a -> FreeT (t m) m b -> t m b
+#endif
 intercalateT f (FreeT m) = do
   val <- lift m
   case val of
diff --git a/src/Control/Monad/Trans/Free/Church.hs b/src/Control/Monad/Trans/Free/Church.hs
--- a/src/Control/Monad/Trans/Free/Church.hs
+++ b/src/Control/Monad/Trans/Free/Church.hs
@@ -146,10 +146,10 @@
   {-# INLINE throwError #-}
   m `catchError` f = toFT $ fromFT m `catchError` (fromFT . f)
 
-instance (MonadCont m) => MonadCont (FT f m) where
+instance MonadCont m => MonadCont (FT f m) where
   callCC f = join . lift $ callCC (\k -> return $ f (lift . k . return))
 
-instance (Functor f, MonadReader r m) => MonadReader r (FT f m) where
+instance MonadReader r m => MonadReader r (FT f m) where
   ask = lift ask
   {-# INLINE ask #-}
   local f = hoistFT (local f)
@@ -165,7 +165,7 @@
   {-# INLINE writer #-}
 #endif
 
-instance (Functor f, MonadState s m) => MonadState s (FT f m) where
+instance MonadState s m => MonadState s (FT f m) where
   get = lift get
   {-# INLINE get #-}
   put = lift . put
@@ -223,7 +223,7 @@
 hoistFT phi (FT m) = FT (\kp kf -> join . phi $ m (return . kp) (\xg -> return . kf (join . phi . xg)))
 
 -- | Lift a natural transformation from @f@ to @g@ into a monad homomorphism from @'FT' f m@ to @'FT' g n@
-transFT :: Monad m => (forall a. f a -> g a) -> FT f m b -> FT g m b
+transFT :: (forall a. f a -> g a) -> FT f m b -> FT g m b
 transFT phi (FT m) = FT (\kp kf -> m kp (\xg -> kf xg . phi))
 
 -- | Pull out and join @m@ layers of @'FreeT' f m a@.
@@ -252,7 +252,11 @@
 -- @
 -- 'retract' . 'liftF' = 'id'
 -- @
+#if __GLASGOW_HASKELL__ < 710
 retract :: (Functor f, Monad f) => F f a -> f a
+#else
+retract :: Monad f => F f a -> f a
+#endif
 retract m = runF m return join
 {-# INLINE retract #-}
 
