    module Test.Hspec.Expectations.Matcher (matchList) where

    import           Prelude hiding (showList)
    import           Data.List

    matchList :: (Show a, Eq a) => [a] -> [a] -> Maybe String
    xs :: [a]
    xs matchList :: [a] -> [a] -> Maybe String
    `matchList` ys :: [a]
    ys
      | [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [a]
    extra Bool -> Bool -> Bool
    && [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [a]
    missing = Maybe String
    forall a. Maybe a
    Nothing
      | Bool
    otherwise = String -> Maybe String
    forall a. a -> Maybe a
    Just (ShowS
    err "")
      where
        extra :: [a]
    extra   = [a]
    xs [a] -> [a] -> [a]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ [a]
    ys
        missing :: [a]
    missing = [a]
    ys [a] -> [a] -> [a]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ [a]
    xs

        msgAndList :: String -> [a] -> ShowS
    msgAndList msg :: String
    msg zs :: [a]
    zs = String -> ShowS
    showString String
    msg ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> ShowS
    forall a. Show a => [a] -> ShowS
    showList [a]
    zs ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ShowS
    showString "\n"
        optMsgList :: String -> [a] -> ShowS
    optMsgList msg :: String
    msg zs :: [a]
    zs = if [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [a]
    zs then ShowS
    forall a. a -> a
    id else String -> [a] -> ShowS
    forall a. Show a => String -> [a] -> ShowS
    msgAndList String
    msg [a]
    zs

        err :: ShowS
        err :: ShowS
    err =
            String -> ShowS
    showString "Actual list is not a permutation of expected list!\n"
          ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [a] -> ShowS
    forall a. Show a => String -> [a] -> ShowS
    msgAndList "  expected list contains:   " [a]
    ys
          ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [a] -> ShowS
    forall a. Show a => String -> [a] -> ShowS
    msgAndList "  actual list contains:     " [a]
    xs
          ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [a] -> ShowS
    forall a. Show a => String -> [a] -> ShowS
    optMsgList "  the missing elements are: " [a]
    missing
          ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [a] -> ShowS
    forall a. Show a => String -> [a] -> ShowS
    optMsgList "  the extra elements are:   " [a]
    extra

    showList :: Show a => [a] -> ShowS
    showList :: [a] -> ShowS
    showList xs :: [a]
    xs = Char -> ShowS
    showChar '[' ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ShowS -> ShowS -> ShowS) -> ShowS -> [ShowS] -> ShowS
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.) (Char -> ShowS
    showChar ']') (ShowS -> [ShowS] -> [ShowS]
    forall a. a -> [a] -> [a]
    intersperse (String -> ShowS
    showString ", ") ([ShowS] -> [ShowS]) -> [ShowS] -> [ShowS]
    forall a b. (a -> b) -> a -> b
    $ (a -> ShowS) -> [a] -> [ShowS]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> ShowS
    forall a. Show a => a -> ShowS
    shows [a]
    xs)