diff --git a/hspec-expectations.cabal b/hspec-expectations.cabal
--- a/hspec-expectations.cabal
+++ b/hspec-expectations.cabal
@@ -1,5 +1,5 @@
 name:             hspec-expectations
-version:          0.6.0.1
+version:          0.6.1
 synopsis:         Catchy combinators for HUnit
 description:      Catchy combinators for HUnit: <https://github.com/sol/hspec-expectations#readme>
 license:          MIT
@@ -27,6 +27,8 @@
   exposed-modules:
       Test.Hspec.Expectations
     , Test.Hspec.Expectations.Contrib
+  other-modules:
+      Test.Hspec.Expectations.Matcher
 
 test-suite spec
   main-is:
diff --git a/src/Test/Hspec/Expectations.hs b/src/Test/Hspec/Expectations.hs
--- a/src/Test/Hspec/Expectations.hs
+++ b/src/Test/Hspec/Expectations.hs
@@ -40,8 +40,10 @@
 import           Test.HUnit (Assertion, (@?=), assertBool, assertFailure)
 import           Control.Exception
 import           Data.Typeable
-import           Data.List ((\\), isInfixOf)
+import           Data.List (isInfixOf)
 
+import           Test.Hspec.Expectations.Matcher
+
 type Expectation = Assertion
 
 -- | This is just an alias for HUnit's `assertFailure`.
@@ -73,9 +75,7 @@
 -- @xs \`shouldMatchList\` ys@ sets the expectation that @xs@ has the same
 -- elements that @ys@ has, possibly in another order
 shouldMatchList :: (Show a, Eq a) => [a] -> [a] -> Expectation
-xs `shouldMatchList` ys = assertBool errorMsg (all null [xs \\ ys, ys \\ xs])
-  where
-    errorMsg = show ys ++ " is not a permutation of " ++ show xs
+xs `shouldMatchList` ys = maybe (return ()) assertFailure (matchList xs ys)
 
 -- |
 -- @action \`shouldReturn\` expected@ sets the expectation that @action@
diff --git a/src/Test/Hspec/Expectations/Matcher.hs b/src/Test/Hspec/Expectations/Matcher.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Hspec/Expectations/Matcher.hs
@@ -0,0 +1,26 @@
+module Test.Hspec.Expectations.Matcher (matchList) where
+
+import           Prelude hiding (showList)
+import           Data.List
+
+matchList :: (Show a, Eq a) => [a] -> [a] -> Maybe String
+xs `matchList` ys
+  | null extra && null missing = Nothing
+  | otherwise = Just (err "")
+  where
+    extra   = xs \\ ys
+    missing = ys \\ xs
+
+    msgAndList msg zs = showString msg . showList zs . showString "\n"
+    optMsgList msg zs = if null zs then id else msgAndList msg zs
+
+    err :: ShowS
+    err =
+        showString "Actual list is not a permutation of expected list!\n"
+      . msgAndList "  expected list contains:   " ys
+      . msgAndList "  actual list contains:     " xs
+      . optMsgList "  the missing elements are: " missing
+      . optMsgList "  the extra elements are:   " extra
+
+showList :: Show a => [a] -> ShowS
+showList xs = showChar '[' . foldr (.) (showChar ']') (intersperse (showString ", ") $ map shows xs)
