diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,7 @@
 Changelog for CmdArgs
 
+0.10.18
+    #47, GHC 8.4 compatibility
 0.10.17
     Add processValueIO for more controlled error messages
     #529, don't include the stack trace in processValue
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -6,24 +6,24 @@
 * It supports programs with multiple modes, such as [darcs](http://darcs.net) or [Cabal](http://haskell.org/cabal/).
 
 A very simple example of a command line processor is:
+```haskell
+data Sample = Sample {hello :: String} deriving (Show, Data, Typeable)
 
-    data Sample = Sample {hello :: String} deriving (Show, Data, Typeable)
-    
-    sample = Sample{hello = def &= help "World argument" &= opt "world"}
-             &= summary "Sample v1"
-    
-    main = print =<< cmdArgs sample
+sample = Sample{hello = def &= help "World argument" &= opt "world"}
+         &= summary "Sample v1"
 
+main = print =<< cmdArgs sample
+```
 Despite being very concise, this processor is already fairly well featured:
 
     $ runhaskell Sample.hs --hello=world
     Sample {hello = "world"}
-    
+
     $ runhaskell Sample.hs --help
     Sample v1, (C) Neil Mitchell 2009
-    
+
     sample [FLAG]
-    
+
       -? --help[=FORMAT]  Show usage information (optional format)
       -V --version        Show version information
       -v --verbose        Higher verbosity
@@ -46,19 +46,19 @@
 ## Hello World Example
 
 The following code defines a complete command line argument processor:
+```haskell
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# OPTIONS_GHC -fno-cse #-}
+module Sample where
+import System.Console.CmdArgs
 
-    {-# LANGUAGE DeriveDataTypeable #-}
-    {-# OPTIONS_GHC -fno-cse #-}
-    module Sample where
-    import System.Console.CmdArgs
-    
-    data Sample = Sample {hello :: String}
-                  deriving (Show, Data, Typeable)
-    
-    sample = Sample{hello = def}
-    
-    main = print =<< cmdArgs sample
+data Sample = Sample {hello :: String}
+              deriving (Show, Data, Typeable)
 
+sample = Sample{hello = def}
+
+main = print =<< cmdArgs sample
+```
 To use the CmdArgs library there are three steps:
 
 * Define a record data type (`Sample`) that contains a field for each argument. This type needs to have instances for `Show`, `Data` and `Typeable`.
@@ -69,15 +69,15 @@
 
     $ runhaskell Sample.hs --hello=world
     Sample {hello = "world"}
-    
+
     $ runhaskell Sample.hs --version
     The sample program
-    
+
     $ runhaskell Sample.hs --help
     The sample program
-    
+
     sample [OPTIONS]
-    
+
       -? --help        Display help message
       -V --version     Print version information
       -h --hello=ITEM
@@ -87,13 +87,13 @@
 ## Specifying Attributes
 
 In order to control the behaviour we can add attributes. For example to add an attribute specifying the help text for the `--hello` argument we can write:
-
-    sample = Sample{hello = def &= help "Who to say hello to"}
-
+```haskell
+sample = Sample{hello = def &= help "Who to say hello to"}
+```
 We can add additional attributes, for example to specify the type of the value expected by hello:
-
-    sample = Sample {hello = def &= help "Who to say hello to" &= typ "WORLD"}
-
+```haskell
+sample = Sample {hello = def &= help "Who to say hello to" &= typ "WORLD"}
+```
 Now when running `--help` the final line is:
 
       -h --hello=WORLD  Who to say hello to
@@ -104,37 +104,37 @@
 ## Multiple Modes
 
 To specify a program with multiple modes, similar to [darcs](http://darcs.net/), we can supply a data type with multiple constructors, for example:
-    
-    data Sample = Hello {whom :: String}
-                | Goodbye
-                  deriving (Show, Data, Typeable)
-    
-    hello = Hello{whom = def}
-    goodbye = Goodbye
-    
-    main = print =<< cmdArgs (modes [hello,goodbye])
+```haskell
+data Sample = Hello {whom :: String}
+            | Goodbye
+              deriving (Show, Data, Typeable)
 
+hello = Hello{whom = def}
+goodbye = Goodbye
+
+main = print =<< cmdArgs (modes [hello,goodbye])
+```
 Compared to the first example, we now have multiple constructors, and a sample value for each constructor is passed to `cmdArgs`. Some sample interactions with this command line are:
 
     $ runhaskell Sample.hs hello --whom=world
     Hello {whom = "world"}
-    
+
     $ runhaskell Sample.hs goodbye
     Goodbye
-    
+
     $ runhaskell Sample.hs --help
     The sample program
-    
+
     sample [OPTIONS]
-    
+
      Common flags
       -? --help       Display help message
       -V --version    Print version information
-    
+
     sample hello [OPTIONS]
-    
+
       -w --whom=ITEM
-    
+
     sample goodbye [OPTIONS]
 
 As before, the behaviour can be customised using attributes.
@@ -154,62 +154,62 @@
 * The `cpp_define` field has an underscore in it's name, which is transformed into a hyphen for the flag name.
 
 The code is:
+```haskell
+{-# LANGUAGE DeriveDataTypeable #-}
+module HLint where
+import System.Console.CmdArgs
 
-    {-# LANGUAGE DeriveDataTypeable #-}
-    module HLint where
-    import System.Console.CmdArgs
-    
-    data HLint = HLint
-        {report :: [FilePath]
-        ,hint :: [FilePath]
-        ,color :: Bool
-        ,ignore_ :: [String]
-        ,show_ :: Bool
-        ,extension :: [String]
-        ,language :: [String]
-        ,utf8 :: Bool
-        ,encoding :: String
-        ,find :: [FilePath]
-        ,test_ :: Bool
-        ,datadir :: [FilePath]
-        ,cpp_define :: [String]
-        ,cpp_include :: [FilePath]
-        ,files :: [FilePath]
-        }
-        deriving (Data,Typeable,Show,Eq)
-    
-    hlint = HLint
-        {report = def &= opt "report.html" &= typFile &= help "Generate a report in HTML"
-        ,hint = def &= typFile &= help "Hint/ignore file to use"
-        ,color = def &= name "c" &= name "colour" &= help "Color the output (requires ANSI terminal)"
-        ,ignore_ = def &= typ "MESSAGE" &= help "Ignore a particular hint"
-        ,show_ = def &= help "Show all ignored ideas"
-        ,extension = def &= typ "EXT" &= help "File extensions to search (defaults to hs and lhs)"
-        ,language = def &= name "X" &= typ "LANG" &= help "Language extension (Arrows, NoCPP)"
-        ,utf8 = def &= help "Use UTF-8 text encoding"
-        ,encoding = def &= typ "ENC" &= help "Choose the text encoding"
-        ,find = def &= typFile &= help "Find hints in a Haskell file"
-        ,test_ = def &= help "Run in test mode"
-        ,datadir = def &= typDir &= help "Override the data directory"
-        ,cpp_define = def &= typ "NAME[=VALUE]" &= help "CPP #define"
-        ,cpp_include = def &= typDir &= help "CPP include path"
-        ,files = def &= args &= typ "FILES/DIRS"
-        } &=
-        verbosity &=
-        help "Suggest improvements to Haskell source code" &=
-        summary "HLint v0.0.0, (C) Neil Mitchell" &=
-        details ["Hlint gives hints on how to improve Haskell code",""
-                ,"To check all Haskell files in 'src' and generate a report type:","  hlint src --report"]
-    
-    mode = cmdArgsMode hlint
+data HLint = HLint
+    {report :: [FilePath]
+    ,hint :: [FilePath]
+    ,color :: Bool
+    ,ignore_ :: [String]
+    ,show_ :: Bool
+    ,extension :: [String]
+    ,language :: [String]
+    ,utf8 :: Bool
+    ,encoding :: String
+    ,find :: [FilePath]
+    ,test_ :: Bool
+    ,datadir :: [FilePath]
+    ,cpp_define :: [String]
+    ,cpp_include :: [FilePath]
+    ,files :: [FilePath]
+    }
+    deriving (Data,Typeable,Show,Eq)
 
+hlint = HLint
+    {report = def &= opt "report.html" &= typFile &= help "Generate a report in HTML"
+    ,hint = def &= typFile &= help "Hint/ignore file to use"
+    ,color = def &= name "c" &= name "colour" &= help "Color the output (requires ANSI terminal)"
+    ,ignore_ = def &= typ "MESSAGE" &= help "Ignore a particular hint"
+    ,show_ = def &= help "Show all ignored ideas"
+    ,extension = def &= typ "EXT" &= help "File extensions to search (defaults to hs and lhs)"
+    ,language = def &= name "X" &= typ "LANG" &= help "Language extension (Arrows, NoCPP)"
+    ,utf8 = def &= help "Use UTF-8 text encoding"
+    ,encoding = def &= typ "ENC" &= help "Choose the text encoding"
+    ,find = def &= typFile &= help "Find hints in a Haskell file"
+    ,test_ = def &= help "Run in test mode"
+    ,datadir = def &= typDir &= help "Override the data directory"
+    ,cpp_define = def &= typ "NAME[=VALUE]" &= help "CPP #define"
+    ,cpp_include = def &= typDir &= help "CPP include path"
+    ,files = def &= args &= typ "FILES/DIRS"
+    } &=
+    verbosity &=
+    help "Suggest improvements to Haskell source code" &=
+    summary "HLint v0.0.0, (C) Neil Mitchell" &=
+    details ["Hlint gives hints on how to improve Haskell code",""
+            ,"To check all Haskell files in 'src' and generate a report type:","  hlint src --report"]
+
+mode = cmdArgsMode hlint
+```
 Produces the `--help` output:
 
     HLint v0.0.0, (C) Neil Mitchell
-    
+
     hlint [OPTIONS] [FILES/DIRS]
     Suggest improvements to Haskell source code
-    
+
     Common flags:
       -r --report[=FILE]            Generate a report in HTML
       -h --hint=FILE                Hint/ignore file to use
@@ -229,13 +229,13 @@
       -V --version                    Print version information
       -v --verbose                    Loud verbosity
       -q --quiet                    Quiet verbosity
-    
+
     Hlint gives hints on how to improve Haskell code
-    
+
     To check all Haskell files in 'src' and generate a report type:
       hlint src --report
-    
 
+
 ### Diffy
 
 The Diffy sample is a based on the idea of creating directory listings and comparing them. The tool can operate in two separate modes, `create` or `diff`. This sample is fictional, but the ideas are drawn from a real program. A few notable features:
@@ -245,47 +245,47 @@
 * Default values are given for the `out` field, which are different in both modes.
 
 The code is:
+```haskell
+{-# LANGUAGE DeriveDataTypeable #-}
+module Diffy where
+import System.Console.CmdArgs
 
-    {-# LANGUAGE DeriveDataTypeable #-}
-    module Diffy where
-    import System.Console.CmdArgs
-    
-    data Diffy = Create {src :: Maybe FilePath, out :: FilePath}
-               | Diff {old :: FilePath, new :: FilePath, out :: FilePath}
-                 deriving (Data,Typeable,Show,Eq)
-    
-    outFlags x = x &= help "Output file" &= typFile
-    
-    create = Create
-        {src = def &= help "Source directory" &= typDir
-        ,out = outFlags "ls.txt"
-        } &= help "Create a fingerprint"
-    
-    diff = Diff
-        {old = def &= typ "OLDFILE" &= argPos 0
-        ,new = def &= typ "NEWFILE" &= argPos 1
-        ,out = outFlags "diff.txt"
-        } &= help "Perform a diff"
-    
-    mode = cmdArgsMode $ modes [create,diff] &= help "Create and compare differences" &= program "diffy" &= summary "Diffy v1.0"
+data Diffy = Create {src :: Maybe FilePath, out :: FilePath}
+           | Diff {old :: FilePath, new :: FilePath, out :: FilePath}
+             deriving (Data,Typeable,Show,Eq)
 
+outFlags x = x &= help "Output file" &= typFile
+
+create = Create
+    {src = def &= help "Source directory" &= typDir
+    ,out = outFlags "ls.txt"
+    } &= help "Create a fingerprint"
+
+diff = Diff
+    {old = def &= typ "OLDFILE" &= argPos 0
+    ,new = def &= typ "NEWFILE" &= argPos 1
+    ,out = outFlags "diff.txt"
+    } &= help "Perform a diff"
+
+mode = cmdArgsMode $ modes [create,diff] &= help "Create and compare differences" &= program "diffy" &= summary "Diffy v1.0"
+```
 And `--help` produces:
 
     Diffy v1.0
-     
+
     diffy [COMMAND] ... [OPTIONS]
       Create and compare differences
-     
+
     Common flags:
       -o --out=FILE     Output file
       -? --help         Display help message
       -V --version     Print version information
-     
+
     diffy create [OPTIONS]
       Create a fingerprint
-     
+
       -s  --src=DIR  Source directory
-     
+
     diffy diff [OPTIONS] OLDFILE NEWFILE
       Perform a diff
 
@@ -298,67 +298,67 @@
 * The `threads` field is in two of the constructors, but not all three. It is given the short flag `-j`, rather than the default `-t`.
 
 The code is:
+```haskell
+{-# LANGUAGE DeriveDataTypeable #-}
+module Maker where
+import System.Console.CmdArgs
 
-    {-# LANGUAGE DeriveDataTypeable #-}
-    module Maker where
-    import System.Console.CmdArgs
-    
-    data Method = Debug | Release | Profile
-                  deriving (Data,Typeable,Show,Eq)
-    
-    data Maker
-        = Wipe
-        | Test {threads :: Int, extra :: [String]}
-        | Build {threads :: Int, method :: Method, files :: [FilePath]}
-          deriving (Data,Typeable,Show,Eq)
-    
-    threadsMsg x = x &= help "Number of threads to use" &= name "j" &= typ "NUM"
-    
-    wipe = Wipe &= help "Clean all build objects"
-    
-    test_ = Test
-        {threads = threadsMsg def
-        ,extra = def &= typ "ANY" &= args
-        } &= help "Run the test suite"
-    
-    build = Build
-        {threads = threadsMsg def
-        ,method = enum
-            [Release &= help "Release build"
-            ,Debug &= help "Debug build"
-            ,Profile &= help "Profile build"]
-        ,files = def &= args
-        } &= help "Build the project" &= auto
-    
-    mode = cmdArgsMode $ modes [build,wipe,test_]
-         &= help "Build helper program"
-         &= program "maker"
-         &= summary "Maker v1.0\nMake it"
+data Method = Debug | Release | Profile
+              deriving (Data,Typeable,Show,Eq)
 
+data Maker
+    = Wipe
+    | Test {threads :: Int, extra :: [String]}
+    | Build {threads :: Int, method :: Method, files :: [FilePath]}
+      deriving (Data,Typeable,Show,Eq)
+
+threadsMsg x = x &= help "Number of threads to use" &= name "j" &= typ "NUM"
+
+wipe = Wipe &= help "Clean all build objects"
+
+test_ = Test
+    {threads = threadsMsg def
+    ,extra = def &= typ "ANY" &= args
+    } &= help "Run the test suite"
+
+build = Build
+    {threads = threadsMsg def
+    ,method = enum
+        [Release &= help "Release build"
+        ,Debug &= help "Debug build"
+        ,Profile &= help "Profile build"]
+    ,files = def &= args
+    } &= help "Build the project" &= auto
+
+mode = cmdArgsMode $ modes [build,wipe,test_]
+     &= help "Build helper program"
+     &= program "maker"
+     &= summary "Maker v1.0\nMake it"
+```
 And `--help` produces:
 
     Maker v1.0
       Make it
-     
+
     maker [COMMAND] ... [OPTIONS]
       Build helper program
-     
+
     Common flags:
       -? --help     Display help message
       -V --version  Print version information
-     
+
     maker [build] [OPTIONS] [ITEM]
       Build the project
-     
+
       -j --threads=NUM  Number of threads to use
       -r --release      Release build
       -d --debug        Debug build
       -p --profile      Profile build
-     
+
     maker wipe [OPTIONS]
       Clean all build objects
-     
+
     maker test [OPTIONS] [ANY]
       Run the test suite
-     
+
       -j --threads=NUM  Number of threads to use
diff --git a/System/Console/CmdArgs/Explicit/Type.hs b/System/Console/CmdArgs/Explicit/Type.hs
--- a/System/Console/CmdArgs/Explicit/Type.hs
+++ b/System/Console/CmdArgs/Explicit/Type.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 
 module System.Console.CmdArgs.Explicit.Type where
 
@@ -7,6 +8,9 @@
 import Data.List
 import Data.Maybe
 import Data.Monoid
+#if __GLASGOW_HASKELL__ >= 802
+import Data.Semigroup (Semigroup(..))
+#endif
 import Prelude
 
 
@@ -47,6 +51,11 @@
 
 instance Functor Group where
     fmap f (Group a b c) = Group (map f a) (map f b) (map (second $ map f) c)
+
+#if __GLASGOW_HASKELL__ > 800
+instance Semigroup (Group a) where
+    (<>) = mappend
+#endif
 
 instance Monoid (Group a) where
     mempty = Group [] [] []
diff --git a/cmdargs.cabal b/cmdargs.cabal
--- a/cmdargs.cabal
+++ b/cmdargs.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.18
 build-type:         Simple
 name:               cmdargs
-version:            0.10.17
+version:            0.10.18
 license:            BSD3
 license-file:       LICENSE
 category:           Console
@@ -33,7 +33,7 @@
 extra-doc-files:
     README.md
     CHANGES.txt
-tested-with:        GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2
+tested-with:        GHC==8.2.1, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2
 
 source-repository head
     type:     git
