diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+0.2.1.2:
+- Fix #36: Compile on GHC >= 8.0
+
 0.2.1.1:
  - Fix #26: Import orphan Foldable Last instance from base-orphans
  - Fix #27: Fix failure when decoding empty [packed] fields
diff --git a/protobuf.cabal b/protobuf.cabal
--- a/protobuf.cabal
+++ b/protobuf.cabal
@@ -1,5 +1,5 @@
 name:                protobuf
-version:             0.2.1.1
+version:             0.2.1.2
 synopsis:            Google Protocol Buffers via GHC.Generics
 description:
   Google Protocol Buffers via GHC.Generics.
@@ -57,6 +57,9 @@
     unordered-containers       >= 0.2
   ghc-options:
     -Wall
+
+  if impl(ghc < 8.0)
+    build-depends: semigroups == 0.18.*
 
 -- executable protoc-gen-hs
   -- default-language:
diff --git a/src/Data/ProtocolBuffers/Message.hs b/src/Data/ProtocolBuffers/Message.hs
--- a/src/Data/ProtocolBuffers/Message.hs
+++ b/src/Data/ProtocolBuffers/Message.hs
@@ -17,10 +17,11 @@
 import Control.Applicative
 import Control.DeepSeq (NFData(..))
 import Data.Foldable
-import Data.Monoid
+import Data.Monoid hiding ((<>))
 import Data.Serialize.Get
 import Data.Serialize.Put
 import Data.Traversable
+import Data.Semigroup (Semigroup(..))
 
 import GHC.Generics
 import GHC.TypeLits
@@ -96,9 +97,12 @@
 newtype Message m = Message {runMessage :: m}
   deriving (Eq, Foldable, Functor, Ord, Show, Traversable)
 
+instance (Generic m, GMessageMonoid (Rep m)) => Semigroup (Message m) where
+  Message x <> Message y = Message . to $ gmappend (from x) (from y)
+
 instance (Generic m, GMessageMonoid (Rep m)) => Monoid (Message m) where
   mempty = Message . to $ gmempty
-  Message x `mappend` Message y = Message . to $ gmappend (from x) (from y)
+  mappend = (<>)
 
 instance (Decode a, Monoid (Message a), KnownNat n) => GDecode (K1 i (Field n (RequiredField (Always (Message a))))) where
   gdecode = fieldDecode (Required . Always)
diff --git a/src/Data/ProtocolBuffers/Types.hs b/src/Data/ProtocolBuffers/Types.hs
--- a/src/Data/ProtocolBuffers/Types.hs
+++ b/src/Data/ProtocolBuffers/Types.hs
@@ -29,7 +29,8 @@
 import Control.DeepSeq (NFData)
 import Data.Bits
 import Data.Foldable as Fold
-import Data.Monoid
+import Data.Monoid hiding ((<>))
+import Data.Semigroup (Semigroup(..))
 import Data.Traversable
 import Data.Typeable
 
@@ -38,25 +39,25 @@
 -- |
 -- 'Value' selects the normal/typical way for encoding scalar (primitive) values.
 newtype Value a       = Value       {runValue       :: a}
-  deriving (Bounded, Eq, Enum, Foldable, Functor, Monoid, Ord, NFData, Show, Traversable, Typeable)
+  deriving (Bounded, Eq, Enum, Foldable, Functor, Semigroup, Monoid, Ord, NFData, Show, Traversable, Typeable)
 
 -- |
 -- 'RequiredField' is a newtype wrapped used to break overlapping instances
 -- for encoding and decoding values
 newtype RequiredField a    = Required    {runRequired    :: a}
-  deriving (Bounded, Eq, Enum, Foldable, Functor, Monoid, Ord, NFData, Show, Traversable, Typeable)
+  deriving (Bounded, Eq, Enum, Foldable, Functor, Semigroup, Monoid, Ord, NFData, Show, Traversable, Typeable)
 
 -- |
 -- 'OptionalField' is a newtype wrapped used to break overlapping instances
 -- for encoding and decoding values
 newtype OptionalField a    = Optional    {runOptional    :: a}
-  deriving (Bounded, Eq, Enum, Foldable, Functor, Monoid, Ord, NFData, Show, Traversable, Typeable)
+  deriving (Bounded, Eq, Enum, Foldable, Functor, Semigroup, Monoid, Ord, NFData, Show, Traversable, Typeable)
 
 -- |
 -- 'RepeatedField' is a newtype wrapped used to break overlapping instances
 -- for encoding and decoding values
 newtype RepeatedField a    = Repeated    {runRepeated    :: a}
-  deriving (Bounded, Eq, Enum, Foldable, Functor, Monoid, Ord, NFData, Show, Traversable, Typeable)
+  deriving (Bounded, Eq, Enum, Foldable, Functor, Semigroup, Monoid, Ord, NFData, Show, Traversable, Typeable)
 
 -- |
 -- Fields are merely a way to hold a field tag along with its type, this shouldn't normally be referenced directly.
@@ -64,7 +65,7 @@
 -- This provides better error messages than older versions which used 'Data.Tagged.Tagged'
 --
 newtype Field (n :: Nat) a = Field {runField :: a}
-  deriving (Bounded, Eq, Enum, Foldable, Functor, Monoid, Ord, NFData, Show, Traversable, Typeable)
+  deriving (Bounded, Eq, Enum, Foldable, Functor, Semigroup, Monoid, Ord, NFData, Show, Traversable, Typeable)
 
 -- |
 -- To provide consistent instances for serialization a 'Traversable' 'Functor' is needed to
@@ -74,9 +75,12 @@
 newtype Always a = Always {runAlways :: a}
   deriving (Bounded, Eq, Enum, Foldable, Functor, Ord, NFData, Show, Traversable, Typeable)
 
+instance Semigroup (Always a) where
+  _ <> y = y
+
 instance Monoid (Always a) where
   mempty = error "Always is not a Monoid"
-  mappend _ y = y
+  mappend = (<>)
 
 -- |
 -- Functions for wrapping and unwrapping record fields.
@@ -175,24 +179,24 @@
 -- |
 -- 'Enumeration' fields use 'Prelude.fromEnum' and 'Prelude.toEnum' when encoding and decoding messages.
 newtype Enumeration a = Enumeration {runEnumeration :: a}
-  deriving (Bounded, Eq, Enum, Foldable, Functor, Ord, Monoid, NFData, Show, Traversable, Typeable)
+  deriving (Bounded, Eq, Enum, Foldable, Functor, Ord, Semigroup, Monoid, NFData, Show, Traversable, Typeable)
 
 -- |
 -- A 'Traversable' 'Functor' used to select packed sequence encoding/decoding.
 newtype PackedField a = PackedField {runPackedField :: a}
-  deriving (Eq, Foldable, Functor, Monoid, NFData, Ord, Show, Traversable, Typeable)
+  deriving (Eq, Foldable, Functor, Semigroup, Monoid, NFData, Ord, Show, Traversable, Typeable)
 
 -- |
 -- A list that is stored in a packed format.
 newtype PackedList a = PackedList {unPackedList :: [a]}
-  deriving (Eq, Foldable, Functor, Monoid, NFData, Ord, Show, Traversable, Typeable)
+  deriving (Eq, Foldable, Functor, Semigroup, Monoid, NFData, Ord, Show, Traversable, Typeable)
 
 -- |
 -- Signed integers are stored in a zz-encoded form.
 newtype Signed a = Signed a
-  deriving (Bits, Bounded, Enum, Eq, Floating, Foldable, Fractional, Functor, Integral, Monoid, NFData, Num, Ord, Real, RealFloat, RealFrac, Show, Traversable, Typeable)
+  deriving (Bits, Bounded, Enum, Eq, Floating, Foldable, Fractional, Functor, Integral, Semigroup, Monoid, NFData, Num, Ord, Real, RealFloat, RealFrac, Show, Traversable, Typeable)
 
 -- |
 -- Fixed integers are stored in little-endian form without additional encoding.
 newtype Fixed a = Fixed a
-  deriving (Bits, Bounded, Enum, Eq, Floating, Foldable, Fractional, Functor, Integral, Monoid, NFData, Num, Ord, Real, RealFloat, RealFrac, Show, Traversable, Typeable)
+  deriving (Bits, Bounded, Enum, Eq, Floating, Foldable, Fractional, Functor, Integral, Semigroup, Monoid, NFData, Num, Ord, Real, RealFloat, RealFrac, Show, Traversable, Typeable)
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -13,7 +13,7 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 import Test.QuickCheck
-import Test.QuickCheck.Property
+import Test.QuickCheck.Property hiding (testCase)
 import Test.Tasty
 import Test.Tasty.HUnit
 import Test.Tasty.QuickCheck
