diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+0.4 (2018-03-18)
+================
+
+* GHC 8.4 compatibility.
+
+* Drop compatibility with GHC 7. GHC 8.4 introduces `Semigroup` as a superclass
+  for monoid, and `Semigroup` is not in `base` prior to GHC 8. To avoid
+  a conditional interface or a dependency on the `semigroups` package, we drop
+  compatibility with GHC 7. There are not other changes in this version, so
+  `ixset-typed-0.3.1.1` remains usable with GHC 7.
+
 0.3.1.1 (2017-08-14)
 ====================
 
diff --git a/ixset-typed.cabal b/ixset-typed.cabal
--- a/ixset-typed.cabal
+++ b/ixset-typed.cabal
@@ -1,5 +1,5 @@
 name:                ixset-typed
-version:             0.3.1.1
+version:             0.4
 synopsis:            Efficient relational queries on Haskell sets.
 description:
     This Haskell package provides a data structure of sets that are indexed
@@ -26,19 +26,19 @@
 build-type:          Simple
 cabal-version:       >= 1.10
 extra-source-files:  CHANGELOG.md
-tested-with:         GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1, GHC == 8.2.1
+tested-with:         GHC == 8.0.1, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.1
 
 source-repository head
   type:              git
   location:          https://github.com/well-typed/ixset-typed.git
 
 library
-  build-depends:     base             >= 4.6 && < 5,
+  build-depends:     base             >= 4.9 && < 5,
                      containers       >= 0.5 && < 1,
                      deepseq          >= 1.3 && < 2,
                      safecopy         >= 0.8 && < 1,
                      syb              >= 0.4 && < 1,
-                     template-haskell >= 2.8 && < 2.13
+                     template-haskell >= 2.8 && < 2.14
 
   hs-source-dirs:    src
   exposed-modules:
@@ -52,7 +52,7 @@
 test-suite test-ixset-typed
   type:              exitcode-stdio-1.0
   build-depends:     ixset-typed,
-                     base             >= 4.6 && < 5,
+                     base             >= 4.9 && < 5,
                      containers       >= 0.5 && < 1,
                      HUnit,
                      QuickCheck,
diff --git a/src/Data/IxSet/Typed.hs b/src/Data/IxSet/Typed.hs
--- a/src/Data/IxSet/Typed.hs
+++ b/src/Data/IxSet/Typed.hs
@@ -180,6 +180,7 @@
      groupBy,
      groupAscBy,
      groupDescBy,
+     indexKeys,
 
      -- * Index creation helpers
      flatten,
@@ -206,6 +207,7 @@
 import           Data.Maybe     (fromMaybe)
 import           Data.Monoid    (Monoid(mempty, mappend))
 import           Data.SafeCopy  (SafeCopy(..), contain, safeGet, safePut)
+import           Data.Semigroup (Semigroup(..))
 import           Data.Set       (Set)
 import qualified Data.Set       as Set
 import           Data.Typeable  (Typeable, cast {- , typeOf -})
@@ -402,6 +404,9 @@
 instance (All NFData ixs, NFData a) => NFData (IxSet ixs a) where
   rnf (IxSet a ixs) = rnf a `seq` rnf ixs
 
+instance Indexable ixs a => Semigroup (IxSet ixs a) where
+  (<>) = mappend
+
 instance Indexable ixs a => Monoid (IxSet ixs a) where
   mempty  = empty
   mappend = union
@@ -941,6 +946,13 @@
   where
     f :: Ix ix a -> [(ix, [a])]
     f (Ix index _) = map (second Set.toList) (Map.toList index)
+
+-- | Returns the list of index keys being used for a particular index.
+indexKeys :: forall ix ixs a . IsIndexOf ix ixs => IxSet ixs a -> [ix]
+indexKeys (IxSet _ indexes) = f (access indexes)
+  where
+    f :: Ix ix a -> [ix]
+    f (Ix index _) = Map.keys index
 
 -- | Returns lists of elements paired with the indices determined by
 -- type inference.
