@@ -130,6 +130,11 @@ import qualified GHC.Exts as Exts
130
130
import Data.Functor.Classes
131
131
#endif
132
132
133
+ #if MIN_VERSION_hashable(1,2,5)
134
+ import qualified Data.Hashable.Lifted as H
135
+ #endif
136
+
137
+ -- | A set of values. A set cannot contain duplicate values.
133
138
------------------------------------------------------------------------
134
139
135
140
-- | Convenience function. Compute a hash value for the given value.
@@ -309,6 +314,34 @@ equalKeys eq t1 t2 = go (toList' t1 []) (toList' t2 [])
309
314
310
315
leafEq (L k _) (L k' _) = eq k k'
311
316
317
+ #if MIN_VERSION_hashable(1,2,5)
318
+ instance H. Hashable2 HashMap where
319
+ liftHashWithSalt2 hk hv salt hm = go salt (toList' hm [] )
320
+ where
321
+ -- go :: Int -> [HashMap k v] -> Int
322
+ go s [] = s
323
+ go s (Leaf _ l : tl)
324
+ = s `hashLeafWithSalt` l `go` tl
325
+ -- For collisions we hashmix hash value
326
+ -- and then array of values' hashes sorted
327
+ go s (Collision h a : tl)
328
+ = (s `H.hashWithSalt` h) `hashCollisionWithSalt` a `go` tl
329
+ go s (_ : tl) = s `go` tl
330
+
331
+ -- hashLeafWithSalt :: Int -> Leaf k v -> Int
332
+ hashLeafWithSalt s (L k v) = (s `hk` k) `hv` v
333
+
334
+ -- hashCollisionWithSalt :: Int -> A.Array (Leaf k v) -> Int
335
+ hashCollisionWithSalt s
336
+ = L. foldl' H. hashWithSalt s . arrayHashesSorted s
337
+
338
+ -- arrayHashesSorted :: Int -> A.Array (Leaf k v) -> [Int]
339
+ arrayHashesSorted s = L. sort . L. map (hashLeafWithSalt s) . A. toList
340
+
341
+ instance (Hashable k ) => H. Hashable1 (HashMap k ) where
342
+ liftHashWithSalt = H. liftHashWithSalt2 H. hashWithSalt
343
+ #endif
344
+
312
345
instance (Hashable k , Hashable v ) => Hashable (HashMap k v ) where
313
346
hashWithSalt salt hm = go salt (toList' hm [] )
314
347
where
@@ -327,13 +360,10 @@ instance (Hashable k, Hashable v) => Hashable (HashMap k v) where
327
360
328
361
hashCollisionWithSalt :: Int -> A. Array (Leaf k v ) -> Int
329
362
hashCollisionWithSalt s
330
- = L. foldl' H. hashWithSalt s . arrayHashesSorted
331
-
332
- arrayHashesSorted :: A. Array (Leaf k v ) -> [Int ]
333
- arrayHashesSorted = L. sort . L. map leafValueHash . A. toList
363
+ = L. foldl' H. hashWithSalt s . arrayHashesSorted s
334
364
335
- leafValueHash :: Leaf k v -> Int
336
- leafValueHash ( L _ v) = H. hash v
365
+ arrayHashesSorted :: Int -> A. Array ( Leaf k v ) -> [ Int ]
366
+ arrayHashesSorted s = L. sort . L. map (hashLeafWithSalt s) . A. toList
337
367
338
368
-- Helper to get 'Leaf's and 'Collision's as a list.
339
369
toList' :: HashMap k v -> [HashMap k v ] -> [HashMap k v ]
0 commit comments