diff --git a/Data/HashMap/Base.hs b/Data/HashMap/Base.hs
--- a/Data/HashMap/Base.hs
+++ b/Data/HashMap/Base.hs
@@ -1,4 +1,8 @@
 {-# LANGUAGE BangPatterns, CPP, DeriveDataTypeable, MagicHash #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+#if __GLASGOW_HASKELL__ >= 708
+{-# LANGUAGE TypeFamilies #-}
+#endif
 {-# OPTIONS_GHC -fno-full-laziness -funbox-strict-fields #-}
 
 module Data.HashMap.Base
@@ -89,6 +93,7 @@
 import Data.Word (Word)
 import GHC.Exts ((==#), build, reallyUnsafePtrEquality#)
 import Prelude hiding (filter, foldr, lookup, map, null, pred)
+import Text.Read hiding (step)
 
 import qualified Data.HashMap.Array as A
 import qualified Data.Hashable as H
@@ -101,6 +106,9 @@
 #if __GLASGOW_HASKELL__ >= 707
 import GHC.Exts (isTrue#)
 #endif
+#if __GLASGOW_HASKELL__ >= 708
+import qualified GHC.Exts as Exts
+#endif
 
 
 ------------------------------------------------------------------------
@@ -166,8 +174,17 @@
 type Bitmap = Word
 type Shift  = Int
 
+instance (Eq k, Hashable k, Read k, Read e) => Read (HashMap k e) where
+    readPrec = parens $ prec 10 $ do
+      Ident "fromList" <- lexP
+      xs <- readPrec
+      return (fromList xs)
+
+    readListPrec = readListPrecDefault
+
 instance (Show k, Show v) => Show (HashMap k v) where
-    show m = "fromList " ++ show (toList m)
+    showsPrec d m = showParen (d > 10) $
+      showString "fromList " . shows (toList m)
 
 instance Traversable (HashMap k) where
     traverse f = traverseWithKey (const f)
@@ -433,11 +450,14 @@
 {-# INLINABLE insertWith #-}
 
 -- | In-place update version of insertWith
-unsafeInsertWith :: (Eq k, Hashable k) => (v -> v -> v) -> k -> v -> HashMap k v
+unsafeInsertWith :: forall k v. (Eq k, Hashable k)
+                 => (v -> v -> v) -> k -> v -> HashMap k v
                  -> HashMap k v
 unsafeInsertWith f k0 v0 m0 = runST (go h0 k0 v0 0 m0)
   where
     h0 = hash k0
+    go :: (Eq k, Hashable k) => Hash -> k -> v -> Shift -> HashMap k v
+       -> ST s (HashMap k v)
     go !h !k x !_ Empty = return $! Leaf h (L k x)
     go h k x s (Leaf hy l@(L ky y))
         | hy == h = if ky == k
@@ -813,7 +833,7 @@
 
 -- | /O(n)/ Filter this map by retaining only elements satisfying a
 -- predicate.
-filterWithKey :: (k -> v -> Bool) -> HashMap k v -> HashMap k v
+filterWithKey :: forall k v. (k -> v -> Bool) -> HashMap k v -> HashMap k v
 filterWithKey pred = go
   where
     go Empty = Empty
@@ -830,6 +850,9 @@
             mary <- A.new_ n
             step ary0 mary b0 0 0 1 n
       where
+        step :: A.Array (HashMap k v) -> A.MArray s (HashMap k v)
+             -> Bitmap -> Int -> Int -> Bitmap -> Int
+             -> ST s (HashMap k v)
         step !ary !mary !b i !j !bi n
             | i >= n = case j of
                 0 -> return Empty
@@ -856,6 +879,9 @@
             mary <- A.new_ n
             step ary0 mary 0 0 n
       where
+        step :: A.Array (Leaf k v) -> A.MArray s (Leaf k v)
+             -> Int -> Int -> Int
+             -> ST s (HashMap k v)
         step !ary !mary i !j n
             | i >= n    = case j of
                 0 -> return Empty
@@ -1085,3 +1111,12 @@
 ptrEq x y = isTrue# (reallyUnsafePtrEquality# x y ==# 1#)
 #endif
 {-# INLINE ptrEq #-}
+
+#if __GLASGOW_HASKELL__ >= 708
+------------------------------------------------------------------------
+-- IsList instance
+instance (Eq k, Hashable k) => Exts.IsList (HashMap k v) where
+    type Item (HashMap k v) = (k, v)
+    fromList = fromList
+    toList   = toList
+#endif
diff --git a/Data/HashSet.hs b/Data/HashSet.hs
--- a/Data/HashSet.hs
+++ b/Data/HashSet.hs
@@ -1,4 +1,7 @@
 {-# LANGUAGE CPP, DeriveDataTypeable #-}
+#if __GLASGOW_HASKELL__ >= 708
+{-# LANGUAGE TypeFamilies #-}
+#endif
 
 ------------------------------------------------------------------------
 -- |
@@ -70,7 +73,12 @@
 import qualified Data.HashMap.Lazy as H
 import qualified Data.List as List
 import Data.Typeable (Typeable)
+import Text.Read
 
+#if __GLASGOW_HASKELL__ >= 708
+import qualified GHC.Exts as Exts
+#endif
+
 -- | A set of values.  A set cannot contain duplicate values.
 newtype HashSet a = HashSet {
       asMap :: HashMap a ()
@@ -96,6 +104,14 @@
     mappend = union
     {-# INLINE mappend #-}
 
+instance (Eq a, Hashable a, Read a) => Read (HashSet a) where
+    readPrec = parens $ prec 10 $ do
+      Ident "fromList" <- lexP
+      xs <- readPrec
+      return (fromList xs)
+
+    readListPrec = readListPrecDefault
+
 instance (Show a) => Show (HashSet a) where
     showsPrec d m = showParen (d > 10) $
       showString "fromList " . shows (toList m)
@@ -221,3 +237,10 @@
 fromList :: (Eq a, Hashable a) => [a] -> HashSet a
 fromList = HashSet . List.foldl' (\ m k -> H.insert k () m) H.empty
 {-# INLINE fromList #-}
+
+#if __GLASGOW_HASKELL__ >= 708
+instance (Eq a, Hashable a) => Exts.IsList (HashSet a) where
+    type Item (HashSet a) = a
+    fromList = fromList
+    toList   = toList
+#endif
diff --git a/tests/HashMapProperties.hs b/tests/HashMapProperties.hs
--- a/tests/HashMapProperties.hs
+++ b/tests/HashMapProperties.hs
@@ -21,7 +21,7 @@
 
 -- Key type that generates more hash collisions.
 newtype Key = K { unK :: Int }
-            deriving (Arbitrary, Eq, Ord, Show)
+            deriving (Arbitrary, Eq, Ord, Read, Show)
 
 instance Hashable Key where
     hashWithSalt salt k = hashWithSalt salt (unK k) `mod` 20
@@ -38,6 +38,9 @@
 pNeq :: [(Key, Int)] -> [(Key, Int)] -> Bool
 pNeq xs = (M.fromList xs /=) `eq` (HM.fromList xs /=)
 
+pReadShow :: [(Key, Int)] -> Bool
+pReadShow xs = M.fromList xs == read (show (M.fromList xs))
+
 pFunctor :: [(Key, Int)] -> Bool
 pFunctor = fmap (+ 1) `eq_` fmap (+ 1)
 
@@ -192,6 +195,7 @@
       testGroup "instances"
       [ testProperty "==" pEq
       , testProperty "/=" pNeq
+      , testProperty "Read/Show" pReadShow
       , testProperty "Functor" pFunctor
       , testProperty "Foldable" pFoldable
       ]
diff --git a/tests/HashSetProperties.hs b/tests/HashSetProperties.hs
--- a/tests/HashSetProperties.hs
+++ b/tests/HashSetProperties.hs
@@ -16,7 +16,7 @@
 
 -- Key type that generates more hash collisions.
 newtype Key = K { unK :: Int }
-            deriving (Arbitrary, Enum, Eq, Integral, Num, Ord, Show, Real)
+            deriving (Arbitrary, Enum, Eq, Integral, Num, Ord, Read, Show, Real)
 
 instance Hashable Key where
     hashWithSalt salt k = hashWithSalt salt (unK k) `mod` 20
@@ -33,6 +33,9 @@
 pNeq :: [Key] -> [Key] -> Bool
 pNeq xs = (Set.fromList xs /=) `eq` (S.fromList xs /=)
 
+pReadShow :: [Key] -> Bool
+pReadShow xs = Set.fromList xs == read (show (Set.fromList xs))
+
 pFoldable :: [Int] -> Bool
 pFoldable = (L.sort . Foldable.foldr (:) []) `eq`
             (L.sort . Foldable.foldr (:) [])
@@ -111,6 +114,7 @@
       testGroup "instances"
       [ testProperty "==" pEq
       , testProperty "/=" pNeq
+      , testProperty "Read/Show" pReadShow
       , testProperty "Foldable" pFoldable
       ]
     -- Basic interface
diff --git a/unordered-containers.cabal b/unordered-containers.cabal
--- a/unordered-containers.cabal
+++ b/unordered-containers.cabal
@@ -1,5 +1,5 @@
 name:           unordered-containers
-version:        0.2.4.0
+version:        0.2.5.0
 synopsis:       Efficient hashing-based container types
 description:
   Efficient hashing-based container types.  The containers have been
