diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,9 @@
+## 0.4.5
+
+* Add Semigroup instance for Query
+* Add a `(Param a) => Param (In (Set a))` instance.
+* Drop testing under GHC 7.8 / lts-2
+
 ## 0.4.4
 
 * Report table name and database in the UnexpectedNull case of ResultError, using the previously empty errMessage field
diff --git a/Database/MySQL/Simple/Param.hs b/Database/MySQL/Simple/Param.hs
--- a/Database/MySQL/Simple/Param.hs
+++ b/Database/MySQL/Simple/Param.hs
@@ -28,6 +28,8 @@
 import Data.Int (Int8, Int16, Int32, Int64)
 import Data.List (intersperse)
 import Data.Monoid (mappend)
+import Data.Set (Set)
+import qualified Data.Set as Set
 import Data.Time.Calendar (Day, showGregorian)
 import Data.Time.Clock (UTCTime)
 import Data.Time.Format (formatTime)
@@ -88,6 +90,9 @@
         Plain (fromChar '(') :
         (intersperse (Plain (fromChar ',')) . map render $ xs) ++
         [Plain (fromChar ')')]
+
+instance (Param a) => Param (In (Set a)) where
+    render = render . fmap Set.toList
 
 instance (Param a) => Param (VaArgs [a]) where
     render (VaArgs []) = Plain $ fromByteString "null"
diff --git a/Database/MySQL/Simple/Types.hs b/Database/MySQL/Simple/Types.hs
--- a/Database/MySQL/Simple/Types.hs
+++ b/Database/MySQL/Simple/Types.hs
@@ -23,6 +23,7 @@
 import Blaze.ByteString.Builder (toByteString)
 import Control.Arrow (first)
 import Data.ByteString (ByteString)
+import Data.Semigroup (Semigroup(..))
 import Data.Monoid (Monoid(..))
 import Data.String (IsString(..))
 import Data.Typeable (Typeable)
@@ -69,9 +70,13 @@
 instance IsString Query where
     fromString = Query . toByteString . Utf8.fromString
 
+instance Semigroup Query where
+    (<>) (Query a) (Query b) = Query (B.append a b)
+    {-# INLINE (<>) #-}
+
 instance Monoid Query where
     mempty = Query B.empty
-    mappend (Query a) (Query b) = Query (B.append a b)
+    mappend = (<>)
     {-# INLINE mappend #-}
 
 -- | A single-value \"collection\".
diff --git a/mysql-simple.cabal b/mysql-simple.cabal
--- a/mysql-simple.cabal
+++ b/mysql-simple.cabal
@@ -1,5 +1,5 @@
 name:           mysql-simple
-version:        0.4.4
+version:        0.4.5
 homepage:       https://github.com/paul-rouse/mysql-simple
 bug-reports:    https://github.com/paul-rouse/mysql-simple/issues
 synopsis:       A mid-level MySQL client library.
@@ -48,11 +48,15 @@
     blaze-builder,
     blaze-textual,
     bytestring >= 0.9,
+    containers,
     mysql >= 0.1.1.1,
     pcre-light,
     old-locale,
     text >= 0.11.0.2,
     time
+  if !impl(ghc >= 8.0)
+    build-depends:
+      semigroups >= 0.11 && < 0.19
 
   ghc-options: -Wall -fwarn-tabs
   if impl(ghc >= 7.10)
@@ -68,8 +72,10 @@
     hs-source-dirs:  test
     ghc-options:     -Wall
     build-depends:   base                    >= 4 && < 5
+                   , blaze-builder
                    , hspec
                    , mysql-simple
+                   , text
 
 source-repository head
   type:     git
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -4,4 +4,4 @@
 packages:
 - '.'
 extra-deps: []
-resolver: lts-9.9
+resolver: lts-6.23
diff --git a/test/main.hs b/test/main.hs
--- a/test/main.hs
+++ b/test/main.hs
@@ -1,27 +1,54 @@
-{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE CPP, OverloadedStrings #-}
 
-import Control.Exception     (bracket)
-import Database.MySQL.Simple (ConnectInfo (..), defaultConnectInfo,
-                              connect, close,
-                              query_, Only (..))
+import Control.Exception (bracket)
+import Data.Text (Text)
+import Database.MySQL.Simple
+import Database.MySQL.Simple.Param
 import Test.Hspec
+import Blaze.ByteString.Builder (toByteString)
+#if MIN_VERSION_base(4,8,2)
+#else
+import Control.Applicative
+import Data.Monoid
+#endif
 
 -- This is how to connect to our test database
 testConn :: ConnectInfo
 testConn = defaultConnectInfo {
                connectHost     = "127.0.0.1",
                connectUser     = "test",
-               connectDatabase = "test",
-               connectPassword = "test"
+               connectDatabase = "test"
            }
 
--- Only the most cursory test is done at the moment, simply showing that
--- things hang together sufficiently well that we can talk to the database
--- server.
---
 main :: IO ()
-main = bracket (connect testConn) close $ \conn -> hspec $ do
-    describe "Database" $ do
-      it "seems to be connected" $ do
-        result <- query_ conn "select 1 + 1"
-        result `shouldBe` [Only (2::Int)]
+main =
+  bracket (connect testConn) close $ \conn ->
+    hspec $ do
+      unitSpec
+      integrationSpec conn
+
+unitSpec :: Spec
+unitSpec = do
+  describe "Param a => Param (In [a]) instance" $ do
+    it "renders an empty list correctly" $ do
+      let empty :: [Text]
+          empty = mempty
+
+      case render (In empty) of
+        Plain a -> toByteString a `shouldBe` "(null)"
+        _       -> expectationFailure "expected a Plain"
+
+    it "renders a non-empty list correctly" $ do
+      let l :: [Text]
+          l = ["foo", "bar"]
+
+      case render (In l) of
+        Many [Plain _, Escape "foo", Plain _, Escape "bar", Plain _] -> pure ()
+        _ -> expectationFailure "expected a Many with specific contents"
+
+integrationSpec :: Connection -> Spec
+integrationSpec conn = do
+  describe "the library" $ do
+    it "can connect to a database" $ do
+      result <- query_ conn "select 1 + 1"
+      result `shouldBe` [Only (2::Int)]
