@@ -98,6 +98,7 @@ import Control.DeepSeq (NFData(rnf))
98
98
import Control.Monad.ST (ST )
99
99
import Data.Bits ((.&.) , (.|.) , complement )
100
100
import Data.Data hiding (Typeable )
101
+ import Data.Ord (comparing )
101
102
import qualified Data.Foldable as Foldable
102
103
import qualified Data.List as L
103
104
import GHC.Exts ((==#) , build , reallyUnsafePtrEquality #)
@@ -201,9 +202,6 @@ instance Traversable (HashMap k) where
201
202
instance (Eq k , Eq v ) => Eq (HashMap k v ) where
202
203
(==) = equal
203
204
204
- instance (Hashable k , Hashable v ) => Hashable (HashMap k v ) where
205
- hashWithSalt = foldlWithKey' (\ h k v -> h `H.hashWithSalt` k `H.hashWithSalt` v)
206
-
207
205
equal :: (Eq k , Eq v ) => HashMap k v -> HashMap k v -> Bool
208
206
equal t1 t2 = go (toList' t1 [] ) (toList' t2 [] )
209
207
where
@@ -221,11 +219,26 @@ equal t1 t2 = go (toList' t1 []) (toList' t2 [])
221
219
go [] [] = True
222
220
go _ _ = False
223
221
224
- toList' (BitmapIndexed _ ary) a = A. foldr toList' a ary
225
- toList' (Full ary) a = A. foldr toList' a ary
226
- toList' l@ (Leaf _ _) a = l : a
227
- toList' c@ (Collision _ _) a = c : a
228
- toList' Empty a = a
222
+ instance (Hashable k , Ord k , Hashable v ) => Hashable (HashMap k v ) where
223
+ hashWithSalt salt = L. foldl' (\ h (L k v) -> h `H.hashWithSalt` k `H.hashWithSalt` v) salt . toList''
224
+ where
225
+ -- Order 'Leaf' s with (hash, k) ordering
226
+ toList'' :: HashMap k v -> [Leaf k v ]
227
+ toList'' hm = concatMap f (toList' hm [] )
228
+ f :: HashMap k v -> [Leaf k v ]
229
+ f (Leaf _ l) = [l]
230
+ f (Collision _ a) = L. sortBy (comparing leafKey) (A. toList a)
231
+ f _ = []
232
+ leafKey :: Leaf k v -> k
233
+ leafKey (L k _) = k
234
+
235
+ -- Helper to get 'Leaf's and 'Collision's as a list.
236
+ toList' :: HashMap k v -> [HashMap k v ] -> [HashMap k v ]
237
+ toList' (BitmapIndexed _ ary) a = A. foldr toList' a ary
238
+ toList' (Full ary) a = A. foldr toList' a ary
239
+ toList' l@ (Leaf _ _) a = l : a
240
+ toList' c@ (Collision _ _) a = c : a
241
+ toList' Empty a = a
229
242
230
243
-- Helper function to detect 'Leaf's and 'Collision's.
231
244
isLeafOrCollision :: HashMap k v -> Bool
0 commit comments