diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,11 @@
+shell-monad (0.6.5) unstable; urgency=medium
+
+  * Fix some documentation typos.
+  * Improvements to build with GHC 7.10.3 - 8.4.3. (Thanks, Simon Michael.)
+  * Added inline example to documentation.
+
+ -- Joey Hess <id@joeyh.name>  Sat, 13 Oct 2018 15:50:44 -0400
+
 shell-monad (0.6.4) unstable; urgency=medium
 
   * Fix build with ghc 7.10.
diff --git a/Control/Monad/Shell.hs b/Control/Monad/Shell.hs
--- a/Control/Monad/Shell.hs
+++ b/Control/Monad/Shell.hs
@@ -1,7 +1,36 @@
 -- | This is a shell monad, for generating shell scripts.
 --
 -- The emphasis is on generating shell code that will work in any POSIX
--- compliant shell.
+-- compliant shell and avoids many common shell pitfalls, including
+-- insufficient quoting, while allowing the Haskell type checker to be
+-- leveraged for additional safety.
+--
+-- Here is a hello world example.
+--
+-- > {-# LANGUAGE OverloadedStrings, ExtendedDefaultRules #-}
+-- > import Control.Monad.Shell
+-- > import Data.Monoid
+-- > import qualified Data.Text.Lazy as T
+-- > import qualified Data.Text.Lazy.IO as T
+-- > default (T.Text)
+-- > 
+-- > main :: IO ()
+-- > main = T.writeFile "hello.sh" $ script $ do
+-- > 	cmd "echo" "hello, world"
+-- > 	username <- newVarFrom (Output (cmd "whoami")) ()
+-- > 	cmd "echo" "from" (WithVar username (<> "'s shell"))
+--
+-- When run, that generates this shell code:
+-- 
+-- > #!/bin/sh
+-- > echo 'hello, world'
+-- > _v="$(whoami)"
+-- > echo from "$_v"''"'"'s shell'
+--
+-- There are several other examples shipped in the examples/ directory
+-- of the shell-monad package. For example, protocol.hs shows how 
+-- shell-monad can be used to implement a shell script that speaks a
+-- protocol that is defined using Haskell data types.
 
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -85,7 +114,7 @@
 
 import qualified Data.Text.Lazy as L
 import qualified Data.Set as S
-import Data.Monoid
+import Data.Semigroup
 import Data.Char
 import System.Posix.Types (Fd)
 import System.Posix.IO (stdInput, stdOutput, stdError)
@@ -221,8 +250,12 @@
 	, envFuncs :: S.Set Func
 	}
 
+instance Semigroup Env where
+	(<>) a b = Env (envVars a <> envVars b) (envFuncs a <> envFuncs b)
+
 instance Monoid Env where
 	mempty = Env mempty mempty
+	-- this is redundant starting with base-4.11 / GHC 8.4:
 	mappend a b = Env (envVars a <> envVars b) (envFuncs a <> envFuncs b)
 
 getEnv :: Script Env
@@ -343,7 +376,7 @@
 --
 -- > demo = script $ do
 -- >   cmd "echo" "hello, world"
--- >   name <- newVar "name"
+-- >   name <- newVar ()
 -- >   readVar name
 -- >   cmd "echo" "hello" name
 --
@@ -456,7 +489,7 @@
 -- v1 <- 'newVar' ()
 -- @
 --
--- To provide a naming hint, use either 'NamedLike'.
+-- To provide a naming hint, use 'NamedLike'.
 --
 -- @
 -- v1 <- 'newVar' ('NamedLike' \"x\")
@@ -506,7 +539,7 @@
 -- variable.
 --
 -- > home <- globalVar "HOME"
--- > cabalDir <- newVarContaining (WithVar home (<> "/.cabal")) ()
+-- > cabalDir <- newVarFrom (WithVar home (<> "/.cabal")) ()
 -- 
 -- Or to capture the output of an arithmetic operation.
 --
diff --git a/Control/Monad/Shell/Quote.hs b/Control/Monad/Shell/Quote.hs
--- a/Control/Monad/Shell/Quote.hs
+++ b/Control/Monad/Shell/Quote.hs
@@ -1,5 +1,6 @@
 -- | Shell quoting
 
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -12,7 +13,9 @@
 
 import qualified Data.Text.Lazy as L
 import Data.String
-import Data.Monoid
+#if !(MIN_VERSION_base(4,11,0))
+import Data.Semigroup
+#endif
 import Data.Char
 
 -- | A value that is safely quoted so that it can be exposed to the shell.
@@ -20,7 +23,7 @@
 -- While the constructor is exposed, you should avoid directly constucting
 -- Quoted values. Instead, use 'quote'.
 newtype Quoted a = Q { getQ :: a }
-	deriving (Eq, Ord, Show, Monoid)
+	deriving (Eq, Ord, Show, Semigroup, Monoid)
 
 -- | Quotes a value to allow it to be safely exposed to the shell.
 --
diff --git a/examples/hello.hs b/examples/hello.hs
new file mode 100644
--- /dev/null
+++ b/examples/hello.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE OverloadedStrings, ExtendedDefaultRules #-}
+import Control.Monad.Shell
+import Data.Monoid
+import qualified Data.Text.Lazy as T
+import qualified Data.Text.Lazy.IO as T
+default (T.Text)
+
+main :: IO ()
+main = T.writeFile "hello.sh" $ script $ do
+	cmd "echo" "hello, world"
+	username <- newVarFrom (Output (cmd "whoami")) ()
+	cmd "echo" "from" (WithVar username (<> "'s shell"))
diff --git a/shell-monad.cabal b/shell-monad.cabal
--- a/shell-monad.cabal
+++ b/shell-monad.cabal
@@ -1,5 +1,5 @@
 Name: shell-monad
-Version: 0.6.4
+Version: 0.6.5
 Cabal-Version: >= 1.8
 License: BSD3
 Maintainer: Joey Hess <id@joeyh.name>
@@ -18,6 +18,7 @@
   examples/santa.hs
   examples/protocol.hs
   examples/fib.hs
+  examples/hello.hs
 
 Library
   GHC-Options: -Wall -fno-warn-tabs
@@ -25,6 +26,8 @@
     Control.Monad.Shell
     Control.Monad.Shell.Quote
   Build-Depends: base (>= 4.5), base < 5, containers, text, unix
+  if !impl(ghc >= 8.0)
+    Build-Depends: semigroups == 0.18.*
 
 source-repository head
   type: git
