diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,44 @@
+## 0.4.1
+
+- Fix build with semialign-1.3
+
+## 0.4
+
+- Drop `ansi-wl-pprint` dependency, use `prettyprinter` directly.
+  The naming of functions still uses `ansiWl*` naming scheme, to avoid breaking
+  too many things. Technically, these functions are still compatible with
+  `ansi-wl-pprint` versions which use `prettyprinter` underneath.
+
+## 0.3.4
+
+- Remove 'Eq a' requirement from 'ediffGolden'. The constraint wasn't used, as we only compare 'Expr' representations.
+
+## 0.3.3
+
+- Change 'ediffGolden' so that parse errors in expected file don't cause the hard failure.
+  This way you may `--accept` new results even when expected files are broken, e.g. due merge conflict markers.
+  For now the change is a bit a hack to avoid breaking change in type-signature of `ediffGolden/1`.
+
+## 0.3.2
+
+- Add 'ediffGolden1', a variant of 'ediffGolden' with an additional argument.
+
+## 0.3.1
+
+- Support GHC-8.6.5...9.10.1
+
+## 0.3
+
+- Breaking change:
+  Make HashSet and HashMap ToExpr instances sort the resulting
+  lists of expressions.
+  This makes the results deterministic.
+  ... but your golden files will need adjustment.
+  https://github.com/haskellari/tree-diff/issues/67
+
+- Add `Ord Expr` and `Ord OMap` instances
+- Depend on `data-array-byte` to provide more `ByteArray` instances
+
 ## 0.2.2
 
 - Add instances for base and primitive's `ByteArray`s.
diff --git a/src/Data/TreeDiff/Class.hs b/src/Data/TreeDiff/Class.hs
--- a/src/Data/TreeDiff/Class.hs
+++ b/src/Data/TreeDiff/Class.hs
@@ -1,14 +1,12 @@
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE ConstraintKinds     #-}
 {-# LANGUAGE DefaultSignatures   #-}
+{-# LANGUAGE EmptyCase           #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE GADTs               #-}
 {-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeOperators       #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
-{-# LANGUAGE EmptyCase           #-}
-#endif
 -- | A 'ToExpr' class.
 module Data.TreeDiff.Class (
     ediff,
@@ -20,9 +18,9 @@
     GToExpr,
     ) where
 
-import Data.Foldable    (toList)
-import Data.List.Compat (uncons)
-import Data.Proxy       (Proxy (..))
+import Data.Foldable (toList)
+import Data.List     (sort, uncons)
+import Data.Proxy    (Proxy (..))
 import GHC.Generics
        (Constructor (..), Generic (..), K1 (..), M1 (..), Selector (..),
        U1 (..), V1, (:*:) (..), (:+:) (..))
@@ -42,10 +40,6 @@
 import Data.Word
 import Numeric.Natural       (Natural)
 
-#ifdef MIN_VERSION_generic_deriving
-import Generics.Deriving.Instances ()
-#endif
-
 import qualified Data.Monoid    as Mon
 import qualified Data.Ratio     as Ratio
 import qualified Data.Semigroup as Semi
@@ -93,11 +87,9 @@
 import qualified Data.HashSet        as HS
 
 -- aeson
-import qualified Data.Aeson as Aeson
-#if MIN_VERSION_aeson(2,0,0)
+import qualified Data.Aeson        as Aeson
 import qualified Data.Aeson.Key    as Key
 import qualified Data.Aeson.KeyMap as KM
-#endif
 
 -- strict
 import qualified Data.Strict as Strict
@@ -106,11 +98,7 @@
 import Data.These (These (..))
 
 -- primitive
-import qualified Data.Primitive as Prim
-
-#if MIN_VERSION_base(4,17,0)
-import Data.Array.Byte (ByteArray (..))
-#endif
+import qualified Data.Primitive  as Prim
 
 -- $setup
 -- >>> :set -XDeriveGeneric
@@ -201,11 +189,7 @@
     gsumToExpr (R1 x) = gsumToExpr x
 
 instance GSumToExpr V1 where
-#if __GLASGOW_HASKELL__ >= 708
     gsumToExpr x = case x of {}
-#else
-    gsumToExpr x = x `seq` error "panic: V1 value"
-#endif
 
 instance (Constructor c, GProductToExpr f) => GSumToExpr (M1 i c f) where
     gsumToExpr z@(M1 x) = case gproductToExpr x of
@@ -550,9 +534,9 @@
 -------------------------------------------------------------------------------
 
 instance (ToExpr k, ToExpr v) => ToExpr (HM.HashMap k v) where
-    toExpr x = App "HM.fromList" [ toExpr $ HM.toList x ]
+    toExpr x = App "HM.fromList" [ Lst $ sort $ map toExpr $ HM.toList x ]
 instance (ToExpr k) => ToExpr (HS.HashSet k) where
-    toExpr x = App "HS.fromList" [ toExpr $ HS.toList x ]
+    toExpr x = App "HS.fromList" [ Lst $ sort $ map toExpr $ HS.toList x ]
 
 -------------------------------------------------------------------------------
 -- aeson
@@ -560,13 +544,11 @@
 
 instance ToExpr Aeson.Value
 
-#if MIN_VERSION_aeson(2,0,0)
 instance ToExpr Key.Key where
     toExpr = stringToExpr "Key.concat" . unconcat T.uncons . Key.toText
 
 instance ToExpr a => ToExpr (KM.KeyMap a) where
     toExpr x = App "KM.fromList" [ toExpr $ KM.toList x ]
-#endif
 
 -------------------------------------------------------------------------------
 -- strict
@@ -600,11 +582,3 @@
 -- | @since 0.2.2
 instance ToExpr Prim.ByteArray where
     toExpr ba = App "Prim.byteArrayFromList" [toExpr (Prim.foldrByteArray (:) [] ba :: [Word8])]
-
-#if MIN_VERSION_base(4,17,0)
--- | @since 0.2.2
-instance ToExpr ByteArray where
-    toExpr (ByteArray ba) = App "byteArrayFromList" [toExpr (Prim.foldrByteArray (:) [] (Prim.ByteArray ba) :: [Word8])]
-#endif
-
--- TODO: add more instances
diff --git a/src/Data/TreeDiff/Expr.hs b/src/Data/TreeDiff/Expr.hs
--- a/src/Data/TreeDiff/Expr.hs
+++ b/src/Data/TreeDiff/Expr.hs
@@ -9,9 +9,6 @@
     exprDiff,
     ) where
 
-import Prelude ()
-import Prelude.Compat
-
 import Control.DeepSeq (NFData (..))
 import Data.Semialign  (alignWith)
 import Data.These      (These (..))
@@ -35,7 +32,7 @@
     = App ConstructorName [Expr]                 -- ^ application
     | Rec ConstructorName (OMap FieldName Expr)  -- ^ record constructor
     | Lst [Expr]                                 -- ^ list constructor
-  deriving (Eq, Show)
+  deriving (Eq, Ord, Show)
 
 instance NFData Expr where
     rnf (App n es) = rnf n `seq` rnf es
diff --git a/src/Data/TreeDiff/Golden.hs b/src/Data/TreeDiff/Golden.hs
--- a/src/Data/TreeDiff/Golden.hs
+++ b/src/Data/TreeDiff/Golden.hs
@@ -1,19 +1,21 @@
+{-# LANGUAGE ScopedTypeVariables #-}
 -- | "Golden tests" using 'ediff' comparison.
 module Data.TreeDiff.Golden (
     ediffGolden,
+    ediffGolden1,
 ) where
 
 import Data.TreeDiff
-import Prelude ()
-import Prelude.Compat
 import System.Console.ANSI (SGR (Reset), setSGRCode)
 import Text.Parsec         (eof, parse)
 import Text.Parsec.Text ()
 
-import qualified Data.ByteString              as BS
-import qualified Data.Text                    as T
-import qualified Data.Text.Encoding           as TE
-import qualified Text.PrettyPrint.ANSI.Leijen as WL
+import qualified Data.ByteString               as BS
+import qualified Data.Text                     as T
+import qualified Data.Text.Encoding            as TE
+import qualified Data.Text.Lazy                as TL
+import qualified Prettyprinter                 as PP
+import qualified Prettyprinter.Render.Terminal as PP.A
 
 -- | Make a golden tests.
 --
@@ -37,25 +39,46 @@
 -- for a proper example.
 --
 ediffGolden
-    :: (Eq a, ToExpr a)
+    :: ToExpr a
     => (testName -> IO Expr -> IO Expr -> (Expr -> Expr -> IO (Maybe String)) -> (Expr -> IO ()) -> testTree) -- ^ 'goldenTest'
     -> testName  -- ^ test name
     -> FilePath  -- ^ path to "golden file"
     -> IO a      -- ^ result value
     -> testTree
-ediffGolden impl testName fp x = impl testName expect actual cmp wrt
+ediffGolden impl testName fp x = ediffGolden1 impl' testName fp (\() -> x) where
+    impl' n expect actual = impl n expect (actual ())
+
+-- | Like 'ediffGolden1' but with an additional argument for generation of actual value.
+--
+-- @since 0.3.2
+--
+ediffGolden1
+    :: forall a arg testName testTree. ToExpr a
+    => (testName -> IO Expr -> (arg -> IO Expr) -> (Expr -> Expr -> IO (Maybe String)) -> (Expr -> IO ()) -> testTree) -- ^ 'goldenTest'
+    -> testName  -- ^ test name
+    -> FilePath  -- ^ path to "golden file"
+    -> (arg -> IO a)      -- ^ result value
+    -> testTree
+ediffGolden1 impl testName fp x = impl testName expect actual cmp wrt
   where
-    actual = fmap toExpr x
+    actual :: arg -> IO Expr
+    actual arg = fmap toExpr (x arg)
+
+    expect :: IO Expr
     expect = do
         contents <- BS.readFile fp
         case parse (exprParser <* eof) fp $ TE.decodeUtf8 contents of
-            Left err -> print err >> fail "parse error"
+            Left err -> return $ App "ParseError" [toExpr fp, toExpr (show err)]
             Right r  -> return r
+
+    cmp :: Expr -> Expr -> IO (Maybe [Char])
     cmp a b
         | a == b    = return Nothing
         | otherwise = return $ Just $
             setSGRCode [Reset] ++ showWL (ansiWlEditExprCompact $ ediff a b)
-    wrt expr = BS.writeFile fp $ TE.encodeUtf8 $ T.pack $ showWL (WL.plain (ansiWlExpr expr)) ++ "\n"
+    wrt expr = BS.writeFile fp $ TE.encodeUtf8 $ T.pack $ showWL (PP.unAnnotate (ansiWlExpr expr)) ++ "\n"
 
-showWL :: WL.Doc -> String
-showWL doc = WL.displayS (WL.renderSmart 0.4 80 doc) ""
+showWL :: PP.Doc PP.A.AnsiStyle -> String
+showWL doc
+    = TL.unpack $ PP.A.renderLazy
+    $ PP.layoutSmart PP.LayoutOptions { PP.layoutPageWidth = PP.AvailablePerLine 80 0.4  } doc
diff --git a/src/Data/TreeDiff/OMap.hs b/src/Data/TreeDiff/OMap.hs
--- a/src/Data/TreeDiff/OMap.hs
+++ b/src/Data/TreeDiff/OMap.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP           #-}
 {-# LANGUAGE DeriveFunctor #-}
 -- | Map which remembers the 'fromList' order.
 -- This module is minimal on purpose.
@@ -15,18 +14,15 @@
     elems,
 ) where
 
-import Data.List      (sortBy)
-import Data.Ord       (comparing)
-import Data.Semialign (Semialign (..))
-import Data.These     (These (..))
-import Control.DeepSeq  (NFData (..))
+import Prelude hiding (zipWith)
 
-#if MIN_VERSION_containers(0,5,0)
-import qualified Data.Map.Strict as Map
-#else
-import qualified Data.Map as Map
-#endif
+import Control.DeepSeq (NFData (..))
+import Data.List       (sortBy)
+import Data.Ord        (comparing)
+import Data.Semialign  (Semialign(..), Unzip (..), Zip (..), unzipDefault)
+import Data.These      (These (..))
 
+import qualified Data.Map.Strict as Map
 import qualified Test.QuickCheck as QC
 
 -- $setup
@@ -61,13 +57,11 @@
 -- False
 --
 instance (Eq k, Eq v) => Eq (OMap k v) where
-    xs == ys = go (toAscList xs) (toAscList ys) where
-        go [] [] = True
-        go _  [] = False
-        go [] _  = False
-        go ((k1, v1) : kvs1) ((k2, v2) : kvs2) =
-            k1 == k2 && v1 == v2 && go kvs1 kvs2
+    xs == ys = toAscList xs == toAscList ys
 
+instance (Ord k, Ord v) => Ord (OMap k v) where
+    compare xs ys = compare (toAscList xs) (toAscList ys)
+
 -------------------------------------------------------------------------------
 -- deepseq
 -------------------------------------------------------------------------------
@@ -156,3 +150,11 @@
         g (This (Val i x))            = Val i (f (This x))
         g (That (Val j y))            = Val j (f (That y))
         g (These (Val i x) (Val j y)) = Val (min i j) (f (These x y))
+
+instance Ord k => Zip (OMap k) where
+    zipWith f (OMap xs) (OMap ys) = OMap (zipWith g xs ys) where
+        g (Val i x) (Val j y) = Val (min i j) (f x y)
+
+-- Ord k is required for semialign <1.4
+instance Ord k => Unzip (OMap k) where
+    unzip = unzipDefault
diff --git a/src/Data/TreeDiff/Parser.hs b/src/Data/TreeDiff/Parser.hs
--- a/src/Data/TreeDiff/Parser.hs
+++ b/src/Data/TreeDiff/Parser.hs
@@ -8,8 +8,6 @@
 
 import Control.Applicative (many, optional, (<|>))
 import Data.Char           (chr, isAlphaNum, isPunctuation, isSymbol)
-import Prelude ()
-import Prelude.Compat
 
 import Text.Parser.Char            (CharParsing (anyChar, char, satisfy))
 import Text.Parser.Combinators     (between, (<?>))
diff --git a/src/Data/TreeDiff/Pretty.hs b/src/Data/TreeDiff/Pretty.hs
--- a/src/Data/TreeDiff/Pretty.hs
+++ b/src/Data/TreeDiff/Pretty.hs
@@ -10,7 +10,7 @@
     prettyExpr,
     prettyEditExpr,
     prettyEditExprCompact,
-    -- * ansi-wl-pprint
+    -- * prettyprinter
     ansiWlPretty,
     ansiWlExpr,
     ansiWlEditExpr,
@@ -28,11 +28,12 @@
 import Data.Either        (partitionEithers)
 import Data.TreeDiff.Expr
 import Numeric            (showHex)
-import Text.Read.Compat   (readMaybe)
+import Text.Read          (readMaybe)
 
-import qualified Data.TreeDiff.OMap           as OMap
-import qualified Text.PrettyPrint             as HJ
-import qualified Text.PrettyPrint.ANSI.Leijen as WL
+import qualified Data.TreeDiff.OMap            as OMap
+import qualified Prettyprinter                 as PP
+import qualified Prettyprinter.Render.Terminal as PP.A
+import qualified Text.PrettyPrint              as HJ
 
 -- $setup
 -- >>> import qualified Data.TreeDiff.OMap as OMap
@@ -215,56 +216,73 @@
 -- ansi-wl-pprint
 -------------------------------------------------------------------------------
 
--- | 'Pretty' via @ansi-wl-pprint@ library (with colors).
-ansiWlPretty :: Pretty WL.Doc
+-- | 'Pretty' via @prettyprinter@ library (with colors).
+ansiWlPretty :: Pretty (PP.Doc PP.A.AnsiStyle)
 ansiWlPretty = Pretty
-    { ppCon    = WL.text
-    , ppRec    = \c xs -> ansiGroup (c WL.<+> WL.lbrace) WL.rbrace
-               $ map (\(fn, d) -> WL.text fn WL.<+> WL.equals WL.</> d) xs
-    , ppLst    = ansiGroup WL.lbracket WL.rbracket
-    , ppCpy    = WL.dullwhite
-    , ppIns    = \d -> WL.green $ WL.plain $ WL.char '+' WL.<> d
-    , ppDel    = \d -> WL.red   $ WL.plain $ WL.char '-' WL.<> d
-    , ppApp    = \f xs -> WL.group $ WL.nest 2 $ f WL.<$> WL.vsep xs
-    , ppEdits  = WL.sep
-    , ppEllip  = WL.text "..."
-    , ppParens = WL.parens
+    { ppCon    = ppText
+    , ppRec    = \c xs -> ansiGroup (c PP.<+> PP.lbrace) PP.rbrace
+               $ map (\(fn, d) -> ppText fn PP.<+> (PP.equals PP.<> PP.softline PP.<> d)) xs
+    , ppLst    = ansiGroup PP.lbracket PP.rbracket
+    , ppCpy    = ppDullWhite
+    , ppIns    = \d -> ppGreen $ PP.unAnnotate $ ppChar '+' PP.<> d
+    , ppDel    = \d -> ppRed   $ PP.unAnnotate $ ppChar '-' PP.<> d
+    , ppApp    = \f xs -> PP.group $ PP.nest 2 $ f PP.<> PP.line PP.<> PP.vsep xs
+    , ppEdits  = PP.sep
+    , ppEllip  = ppText "..."
+    , ppParens = PP.parens
     }
 
-ansiGroup :: WL.Doc -> WL.Doc -> [WL.Doc] -> WL.Doc
-ansiGroup l r xs = WL.group $ WL.nest 2 (l WL.<$$> WL.vsep (WL.punctuate WL.comma xs) WL.<> r)
+ansiGroup :: PP.Doc PP.A.AnsiStyle -> PP.Doc PP.A.AnsiStyle -> [PP.Doc PP.A.AnsiStyle] -> PP.Doc PP.A.AnsiStyle
+ansiGroup l r xs = PP.group $ PP.nest 2 (l PP.<> ppLinebreak PP.<> PP.vsep (PP.punctuate PP.comma xs) PP.<> r)
 
 -- | Pretty print 'Expr' using @ansi-wl-pprint@.
-ansiWlExpr :: Expr -> WL.Doc
+ansiWlExpr :: Expr -> PP.Doc PP.A.AnsiStyle
 ansiWlExpr = ppExpr ansiWlPretty
 
 -- | Pretty print @'Edit' 'EditExpr'@ using @ansi-wl-pprint@.
-ansiWlEditExpr :: Edit EditExpr -> WL.Doc
+ansiWlEditExpr :: Edit EditExpr -> PP.Doc PP.A.AnsiStyle
 ansiWlEditExpr = ppEditExpr ansiWlPretty
 
 -- | Compact 'ansiWlEditExpr'
-ansiWlEditExprCompact :: Edit EditExpr -> WL.Doc
+ansiWlEditExprCompact :: Edit EditExpr -> PP.Doc PP.A.AnsiStyle
 ansiWlEditExprCompact = ppEditExprCompact ansiWlPretty
 
+ppChar :: Char -> PP.Doc PP.A.AnsiStyle
+ppChar = PP.pretty
+
+ppText :: String -> PP.Doc PP.A.AnsiStyle
+ppText = PP.pretty
+
+ppLinebreak :: PP.Doc a
+ppLinebreak = PP.flatAlt PP.line mempty
+
+ppWhite, ppDullWhite, ppRed, ppGreen, ppOnDullRed, ppOnDullGreen :: PP.Doc PP.A.AnsiStyle -> PP.Doc PP.A.AnsiStyle
+ppWhite         = PP.annotate (PP.A.color       PP.A.White)
+ppDullWhite     = PP.annotate (PP.A.colorDull   PP.A.White)
+ppRed           = PP.annotate (PP.A.color       PP.A.Red)
+ppGreen         = PP.annotate (PP.A.color       PP.A.Green)
+ppOnDullRed     = PP.annotate (PP.A.bgColorDull PP.A.Red)
+ppOnDullGreen   = PP.annotate (PP.A.bgColorDull PP.A.Green)
+
 -------------------------------------------------------------------------------
 -- Background
 -------------------------------------------------------------------------------
 
 -- | Like 'ansiWlPretty' but color the background.
-ansiWlBgPretty :: Pretty WL.Doc
+ansiWlBgPretty :: Pretty (PP.Doc PP.A.AnsiStyle)
 ansiWlBgPretty = ansiWlPretty
-    { ppIns    = \d -> WL.ondullgreen $ WL.white $ WL.plain $ WL.char '+' WL.<> d
-    , ppDel    = \d -> WL.ondullred   $ WL.white $ WL.plain $ WL.char '-' WL.<> d
+    { ppIns    = \d -> ppOnDullGreen $ ppWhite $ PP.unAnnotate $ ppChar '+' PP.<> d
+    , ppDel    = \d -> ppOnDullRed   $ ppWhite $ PP.unAnnotate $ ppChar '-' PP.<> d
     }
 
 -- | Pretty print 'Expr' using @ansi-wl-pprint@.
-ansiWlBgExpr :: Expr -> WL.Doc
+ansiWlBgExpr :: Expr -> PP.Doc PP.A.AnsiStyle
 ansiWlBgExpr = ppExpr ansiWlBgPretty
 
 -- | Pretty print @'Edit' 'EditExpr'@ using @ansi-wl-pprint@.
-ansiWlBgEditExpr :: Edit EditExpr -> WL.Doc
+ansiWlBgEditExpr :: Edit EditExpr -> PP.Doc PP.A.AnsiStyle
 ansiWlBgEditExpr = ppEditExpr ansiWlBgPretty
 
 -- | Compact 'ansiWlBgEditExpr'.
-ansiWlBgEditExprCompact :: Edit EditExpr -> WL.Doc
+ansiWlBgEditExprCompact :: Edit EditExpr -> PP.Doc PP.A.AnsiStyle
 ansiWlBgEditExprCompact = ppEditExprCompact ansiWlBgPretty
diff --git a/src/Data/TreeDiff/QuickCheck.hs b/src/Data/TreeDiff/QuickCheck.hs
--- a/src/Data/TreeDiff/QuickCheck.hs
+++ b/src/Data/TreeDiff/QuickCheck.hs
@@ -7,8 +7,15 @@
 import System.Console.ANSI (SGR (Reset), setSGRCode)
 import Test.QuickCheck     (Property, counterexample)
 
+import qualified Data.Text.Lazy                as TL
+import qualified Prettyprinter                 as PP
+import qualified Prettyprinter.Render.Terminal as PP.A
+
 -- | A variant of '===', which outputs a diff when values are inequal.
 ediffEq :: (Eq a, ToExpr a) => a -> a -> Property
 ediffEq x y = counterexample
-    (setSGRCode [Reset] ++ show (ansiWlEditExpr $ ediff x y))
+    (setSGRCode [Reset] ++ render (ansiWlEditExpr $ ediff x y))
     (x == y)
+
+render :: PP.Doc PP.A.AnsiStyle -> String
+render = TL.unpack . PP.A.renderLazy . PP.layoutPretty PP.defaultLayoutOptions
diff --git a/tests/Tests.hs b/tests/Tests.hs
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -1,20 +1,21 @@
 {-# LANGUAGE DeriveGeneric #-}
 module Main (main) where
 
+import Data.Array.Byte            (ByteArray (..))
 import Data.Proxy                 (Proxy (..))
 import Data.Word                  (Word8)
 import GHC.Generics               (Generic)
-import Prelude ()
-import Prelude.Compat
 import Test.QuickCheck            (Property, counterexample, (===))
 import Test.Tasty                 (TestTree, defaultMain, testGroup)
 import Test.Tasty.Golden.Advanced (goldenTest)
 import Test.Tasty.QuickCheck      (testProperty)
 
-import qualified Text.Parsec                  as P
-import qualified Text.PrettyPrint.ANSI.Leijen as WL
-import qualified Text.Trifecta                as T (eof, parseString)
-import qualified Text.Trifecta.Result         as T (ErrInfo (..), Result (..))
+import qualified Data.HashSet         as HS
+import qualified Data.Primitive       as Prim
+import qualified Prettyprinter        as PP
+import qualified Text.Parsec          as P
+import qualified Text.Trifecta        as T (eof, parseString)
+import qualified Text.Trifecta.Result as T (ErrInfo (..), Result (..))
 
 import Data.TreeDiff
 import Data.TreeDiff.Golden
@@ -72,7 +73,7 @@
 roundtripParsecAnsiWl :: Expr -> Property
 roundtripParsecAnsiWl e = counterexample info $ ediffEq (Just e) res'
   where
-    doc = show (WL.plain (ansiWlExpr e))
+    doc = show (PP.unAnnotate (ansiWlExpr e))
     res = P.parse (exprParser <* P.eof) "<memory>" doc
 
     info = case res of
@@ -151,6 +152,14 @@
 instance ToExpr Positional
 instance ToExpr Empty
 
+-- test that we have both instances.
+data ByteArrays = ByteArrays
+    Prim.ByteArray
+    ByteArray
+  deriving Generic
+
+instance ToExpr ByteArrays
+
 goldenTests :: TestTree
 goldenTests = testGroup "Golden"
     [ ediffGolden goldenTest "exFoo" "fixtures/exfoo.expr" $
@@ -163,5 +172,9 @@
         return $ MyInt3 42
     , ediffGolden goldenTest "Positional" "fixtures/Positional.expr" $
         return $ Positional 12 True 'z'
+
+    -- issue #67
+    , ediffGolden goldenTest "HashSet" "fixtures/HashSet.expr" $
+        return $ HS.fromList [ [x,y] | x <- "abcd", y <- "xyz" ]
     ]
 
diff --git a/tree-diff.cabal b/tree-diff.cabal
--- a/tree-diff.cabal
+++ b/tree-diff.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               tree-diff
-version:            0.2.2
+version:            0.4.1
 synopsis:           Diffing of (expression) trees.
 category:           Data, Testing
 description:
@@ -44,20 +44,17 @@
   README.md
 
 tested-with:
-    GHC ==7.4.2
-     || ==7.6.3
-     || ==7.8.4
-     || ==7.10.3
-     || ==8.0.2
-     || ==8.2.2
-     || ==8.4.4
-     || ==8.6.5
-     || ==8.8.4
-     || ==8.10.4
-     || ==9.0.2
-     || ==9.2.4
-     || ==9.4.1
-  , GHCJS ==8.4
+  GHC ==8.6.5
+   || ==8.8.4
+   || ==8.10.7
+   || ==9.0.2
+   || ==9.2.8
+   || ==9.4.8
+   || ==9.6.7
+   || ==9.8.4
+   || ==9.10.3
+   || ==9.12.2
+   || ==9.14.1
 
 extra-source-files:
   fixtures/exfoo.expr
@@ -70,6 +67,11 @@
   type:     git
   location: https://github.com/phadej/tree-diff.git
 
+flag base-ge-4-17
+  description: @base >=4.17@ (GHC-9.4)
+  default:     True
+  manual:      False
+
 library
   exposed-modules:
     Data.TreeDiff
@@ -85,48 +87,32 @@
 
   -- GHC boot libraries
   build-depends:
-    , base        >=4.5      && <4.18
-    , bytestring  ^>=0.9.2.1 || ^>=0.10.0.2 || ^>=0.11.0.0
-    , containers  ^>=0.4.2.1 || ^>=0.5.0.0 || ^>=0.6.0.1
-    , deepseq     ^>=1.3.0.0 || ^>=1.4.0.0
+    , base        >=4.12.0.0  && <4.23
+    , bytestring  ^>=0.10.8.2 || ^>=0.11.0.0 || ^>=0.12.0.2
+    , containers  ^>=0.6.0.1  || ^>=0.7      || ^>=0.8
+    , deepseq     ^>=1.4.4.0  || ^>=1.5.0.0
     , parsec      ^>=3.1.13.0
     , pretty      ^>=1.1.1.0
-    , text        ^>=1.2.3.0 || ^>=2.0
-    , time        >=1.4      && <1.5 || >=1.5.0.1 && <1.6 || >=1.6.0.1 && <1.7 || >=1.8.0.2 && <1.9 || >=1.9.3 && <1.13
+    , text        ^>=1.2.3.0  || ^>=2.0      || ^>=2.1
+    , time        ^>=1.8.0.2  || ^>=1.9.3    || ^>=1.10     || ^>=1.11 || ^>=1.12 || ^>=1.14 || ^>=1.15
 
   build-depends:
-    , aeson                 ^>=1.4.6.0 || ^>=1.5.6.0 || ^>=2.0.0.0 || ^>=2.1.0.0
-    , ansi-terminal         >=0.10       && <0.12
-    , ansi-wl-pprint        ^>=0.6.8.2
-    , base-compat           >=0.10.5     && <0.11 || >=0.11.0 && <0.13
-    , bytestring-builder    ^>=0.10.8.2.0
-    , hashable              ^>=1.2.7.0 || ^>=1.3.0.0 || ^>=1.4.0.1
-    , parsers               ^>=0.12.10
-    , primitive             ^>=0.7.1.0
-    , QuickCheck            ^>=2.14.2
-    , scientific            ^>=0.3.6.2
-    , semialign             ^>=1.2.0.1
-    , strict                ^>=0.4.0.1
-    , tagged                ^>=0.8.6
-    , these                 ^>=1.1.1.1
-    , unordered-containers  ^>=0.2.8.0
-    , uuid-types            ^>=1.0.3
-    , vector                ^>=0.12.0.0 || ^>=0.13.0.0
-
-  if impl(ghc <7.5)
-    build-depends: ghc-prim
-
-  if !impl(ghc >=8.0)
-    build-depends: semigroups >=0.19.1 && <0.21
-
-  if !impl(ghc >=7.8)
-    build-depends: generic-deriving >=1.13.1 && <1.15
-
-  if !impl(ghc >=7.10)
-    build-depends:
-      , nats          ^>=1.1.2
-      , transformers  ^>=0.3.0.0 || ^>=0.4.2.0 || ^>=0.5.2.0
-      , void          ^>=0.7.3
+    , aeson                        ^>=2.2.0.0
+    , ansi-terminal                ^>=1.1
+    , hashable                     ^>=1.4.4.0  || ^>=1.5.0.0
+    , parsers                      ^>=0.12.11
+    , prettyprinter                ^>=1.7.2
+    , prettyprinter-ansi-terminal  ^>=1.1.4
+    , primitive                    ^>=0.9.0.0
+    , QuickCheck                   ^>=2.14.2   || ^>=2.15    || ^>=2.16.0.0 || ^>=2.18.0.0
+    , scientific                   ^>=0.3.8.0
+    , semialign                    ^>=1.3.1    || ^>=1.4
+    , strict                       ^>=0.5
+    , tagged                       ^>=0.8.8
+    , these                        ^>=1.2.1
+    , unordered-containers         ^>=0.2.20
+    , uuid-types                   ^>=1.0.6
+    , vector                       ^>=0.13.1.0
 
   other-extensions:
     CPP
@@ -151,26 +137,30 @@
 
   -- dependencies from library
   build-depends:
-    , ansi-terminal
-    , ansi-wl-pprint
     , base
-    , base-compat
     , parsec
+    , prettyprinter
     , primitive
     , QuickCheck
-    , tagged
     , tree-diff
+    , unordered-containers
 
-  if impl(ghc <7.5)
-    build-depends: ghc-prim
+  if !flag(base-ge-4-17)
+    build-depends: data-array-byte >=0.1.0.1 && <0.2
 
   -- extra dependencies
   build-depends:
-    , tasty             ^>=1.2 || ^>=1.3.1 || ^>=1.4.2
-    , tasty-golden      ^>=2.3.1.1
-    , tasty-quickcheck  ^>=0.10.1
-    , trifecta          >=2       && <2.2
+    , tasty             ^>=1.5
+    , tasty-golden      ^>=2.3.5
+    , tasty-quickcheck  ^>=0.10.3 || ^>=0.11
+    , trifecta          ^>=2.1.4
 
+  if flag(base-ge-4-17)
+    build-depends: base >=4.17
+
+  else
+    build-depends: base <4.17
+
 benchmark tree-diff-bench
   default-language: Haskell2010
   type:             exitcode-stdio-1.0
@@ -186,5 +176,5 @@
 
   -- extra dependencies
   build-depends:
-    , criterion  ^>=1.6.0.0
-    , Diff       ^>=0.4.0
+    , criterion  ^>=1.6.3.0
+    , Diff       ^>=1.0
