1
1
{-# LANGUAGE BangPatterns, CPP, PatternGuards, MagicHash, UnboxedTuples #-}
2
2
{-# LANGUAGE LambdaCase #-}
3
3
{-# LANGUAGE Trustworthy #-}
4
+ {-# LANGUAGE ScopedTypeVariables #-}
4
5
{-# OPTIONS_HADDOCK not-home #-}
5
6
6
7
------------------------------------------------------------------------
@@ -141,6 +142,8 @@ import Data.Functor.Identity
141
142
#endif
142
143
import Control.Applicative (Const (.. ))
143
144
import Data.Coerce
145
+ import GHC.TypeLits (KnownNat )
146
+ import Data.Proxy (Proxy (.. ))
144
147
145
148
-- $strictness
146
149
--
@@ -155,7 +158,7 @@ import Data.Coerce
155
158
-- * Construction
156
159
157
160
-- | /O(1)/ Construct a map with a single element.
158
- singleton :: (Hashable k ) => k -> v -> HashMap k v
161
+ singleton :: (Hashable k , KnownNat salt ) => k -> v -> HashMapT salt k v
159
162
singleton k ! v = HM. singleton k v
160
163
161
164
------------------------------------------------------------------------
@@ -164,7 +167,7 @@ singleton k !v = HM.singleton k v
164
167
-- | /O(log n)/ Associate the specified value with the specified
165
168
-- key in this map. If this map previously contained a mapping for
166
169
-- the key, the old value is replaced.
167
- insert :: (Eq k , Hashable k ) => k -> v -> HashMap k v -> HashMap k v
170
+ insert :: (Eq k , Hashable k , KnownNat salt ) => k -> v -> HashMapT salt k v -> HashMapT salt k v
168
171
insert k ! v = HM. insert k v
169
172
{-# INLINABLE insert #-}
170
173
@@ -175,11 +178,11 @@ insert k !v = HM.insert k v
175
178
--
176
179
-- > insertWith f k v map
177
180
-- > where f new old = new + old
178
- insertWith :: (Eq k , Hashable k ) => (v -> v -> v ) -> k -> v -> HashMap k v
179
- -> HashMap k v
181
+ insertWith :: forall k v salt . (Eq k , Hashable k , KnownNat salt ) => (v -> v -> v ) -> k -> v -> HashMapT salt k v
182
+ -> HashMapT salt k v
180
183
insertWith f k0 v0 m0 = go h0 k0 v0 0 m0
181
184
where
182
- h0 = hash k0
185
+ h0 = hash ( Proxy :: Proxy salt ) k0
183
186
go ! h ! k x ! _ Empty = leaf h k x
184
187
go h k x s t@ (Leaf hy l@ (L ky y))
185
188
| hy == h = if ky == k
@@ -209,16 +212,16 @@ insertWith f k0 v0 m0 = go h0 k0 v0 0 m0
209
212
{-# INLINABLE insertWith #-}
210
213
211
214
-- | In-place update version of insertWith
212
- unsafeInsertWith :: (Eq k , Hashable k ) => (v -> v -> v ) -> k -> v -> HashMap k v
213
- -> HashMap k v
215
+ unsafeInsertWith :: (Eq k , Hashable k , KnownNat salt ) => (v -> v -> v ) -> k -> v -> HashMapT salt k v
216
+ -> HashMapT salt k v
214
217
unsafeInsertWith f k0 v0 m0 = unsafeInsertWithKey (const f) k0 v0 m0
215
218
{-# INLINABLE unsafeInsertWith #-}
216
219
217
- unsafeInsertWithKey :: (Eq k , Hashable k ) => (k -> v -> v -> v ) -> k -> v -> HashMap k v
218
- -> HashMap k v
220
+ unsafeInsertWithKey :: forall k v salt . (Eq k , Hashable k , KnownNat salt ) => (k -> v -> v -> v ) -> k -> v -> HashMapT salt k v
221
+ -> HashMapT salt k v
219
222
unsafeInsertWithKey f k0 v0 m0 = runST (go h0 k0 v0 0 m0)
220
223
where
221
- h0 = hash k0
224
+ h0 = hash ( Proxy :: Proxy salt ) k0
222
225
go ! h ! k x ! _ Empty = return $! leaf h k x
223
226
go h k x s t@ (Leaf hy l@ (L ky y))
224
227
| hy == h = if ky == k
@@ -251,10 +254,10 @@ unsafeInsertWithKey f k0 v0 m0 = runST (go h0 k0 v0 0 m0)
251
254
252
255
-- | /O(log n)/ Adjust the value tied to a given key in this map only
253
256
-- if it is present. Otherwise, leave the map alone.
254
- adjust :: (Eq k , Hashable k ) => (v -> v ) -> k -> HashMap k v -> HashMap k v
257
+ adjust :: forall k v salt . (Eq k , Hashable k , KnownNat salt ) => (v -> v ) -> k -> HashMapT salt k v -> HashMapT salt k v
255
258
adjust f k0 m0 = go h0 k0 0 m0
256
259
where
257
- h0 = hash k0
260
+ h0 = hash ( Proxy :: Proxy salt ) k0
258
261
go ! _ ! _ ! _ Empty = Empty
259
262
go h k _ t@ (Leaf hy (L ky y))
260
263
| hy == h && ky == k = leaf h k (f y)
@@ -281,7 +284,7 @@ adjust f k0 m0 = go h0 k0 0 m0
281
284
-- | /O(log n)/ The expression @('update' f k map)@ updates the value @x@ at @k@
282
285
-- (if it is in the map). If @(f x)@ is 'Nothing', the element is deleted.
283
286
-- If it is @('Just' y)@, the key @k@ is bound to the new value @y@.
284
- update :: (Eq k , Hashable k ) => (a -> Maybe a ) -> k -> HashMap k a -> HashMap k a
287
+ update :: (Eq k , Hashable k , KnownNat salt ) => (a -> Maybe a ) -> k -> HashMapT salt k a -> HashMapT salt k a
285
288
update f = alter (>>= f)
286
289
{-# INLINABLE update #-}
287
290
@@ -293,7 +296,7 @@ update f = alter (>>= f)
293
296
-- @
294
297
-- 'lookup' k ('alter' f k m) = f ('lookup' k m)
295
298
-- @
296
- alter :: (Eq k , Hashable k ) => (Maybe v -> Maybe v ) -> k -> HashMap k v -> HashMap k v
299
+ alter :: (Eq k , Hashable k , KnownNat salt ) => (Maybe v -> Maybe v ) -> k -> HashMapT salt k v -> HashMapT salt k v
297
300
alter f k m =
298
301
case f (HM. lookup k m) of
299
302
Nothing -> delete k m
@@ -309,15 +312,15 @@ alter f k m =
309
312
-- <https://hackage.haskell.org/package/lens/docs/Control-Lens-At.html#v:at Control.Lens.At>.
310
313
--
311
314
-- @since 0.2.10
312
- alterF :: (Functor f , Eq k , Hashable k )
313
- => (Maybe v -> f (Maybe v )) -> k -> HashMap k v -> f (HashMap k v )
315
+ alterF :: forall f k v salt . (Functor f , Eq k , Hashable k , KnownNat salt )
316
+ => (Maybe v -> f (Maybe v )) -> k -> HashMapT salt k v -> f (HashMapT salt k v )
314
317
-- Special care is taken to only calculate the hash once. When we rewrite
315
318
-- with RULES, we also ensure that we only compare the key for equality
316
319
-- once. We force the value of the map for consistency with the rewritten
317
320
-- version; otherwise someone could tell the difference using a lazy
318
321
-- @f@ and a functor that is similar to Const but not actually Const.
319
322
alterF f = \ ! k ! m ->
320
- let ! h = hash k
323
+ let ! h = hash ( Proxy :: Proxy salt ) k
321
324
mv = lookup' h k m
322
325
in (<$> f mv) $ \ fres ->
323
326
case fres of
@@ -378,18 +381,18 @@ impossibleAdjust = error "Data.HashMap.alterF internal error: impossible adjust"
378
381
--
379
382
-- Failure to abide by these laws will make demons come out of your nose.
380
383
alterFWeird
381
- :: (Functor f , Eq k , Hashable k )
384
+ :: (Functor f , Eq k , Hashable k , KnownNat salt )
382
385
=> f (Maybe v )
383
386
-> f (Maybe v )
384
- -> (Maybe v -> f (Maybe v )) -> k -> HashMap k v -> f (HashMap k v )
387
+ -> (Maybe v -> f (Maybe v )) -> k -> HashMapT salt k v -> f (HashMapT salt k v )
385
388
alterFWeird _ _ f = alterFEager f
386
389
{-# INLINE [0] alterFWeird #-}
387
390
388
391
-- | This is the default version of alterF that we use in most non-trivial
389
392
-- cases. It's called "eager" because it looks up the given key in the map
390
393
-- eagerly, whether or not the given function requires that information.
391
- alterFEager :: (Functor f , Eq k , Hashable k )
392
- => (Maybe v -> f (Maybe v )) -> k -> HashMap k v -> f (HashMap k v )
394
+ alterFEager :: forall f k v salt . (Functor f , Eq k , Hashable k , KnownNat salt )
395
+ => (Maybe v -> f (Maybe v )) -> k -> HashMapT salt k v -> f (HashMapT salt k v )
393
396
alterFEager f ! k ! m = (<$> f mv) $ \ fres ->
394
397
case fres of
395
398
@@ -418,7 +421,7 @@ alterFEager f !k !m = (<$> f mv) $ \fres ->
418
421
-- If the value changed, update the value.
419
422
else insertKeyExists collPos h k v' m
420
423
421
- where ! h = hash k
424
+ where ! h = hash ( Proxy :: Proxy salt ) k
422
425
! lookupRes = lookupRecordCollision h k m
423
426
! mv = case lookupRes of
424
427
Absent -> Nothing
@@ -431,15 +434,15 @@ alterFEager f !k !m = (<$> f mv) $ \fres ->
431
434
432
435
-- | /O(n+m)/ The union of two maps. If a key occurs in both maps,
433
436
-- the provided function (first argument) will be used to compute the result.
434
- unionWith :: (Eq k , Hashable k ) => (v -> v -> v ) -> HashMap k v -> HashMap k v
435
- -> HashMap k v
437
+ unionWith :: (Eq k , Hashable k , KnownNat salt ) => (v -> v -> v ) -> HashMapT salt k v -> HashMapT salt k v
438
+ -> HashMapT salt k v
436
439
unionWith f = unionWithKey (const f)
437
440
{-# INLINE unionWith #-}
438
441
439
442
-- | /O(n+m)/ The union of two maps. If a key occurs in both maps,
440
443
-- the provided function (first argument) will be used to compute the result.
441
- unionWithKey :: (Eq k , Hashable k ) => (k -> v -> v -> v ) -> HashMap k v -> HashMap k v
442
- -> HashMap k v
444
+ unionWithKey :: (Eq k , Hashable k , KnownNat salt ) => (k -> v -> v -> v ) -> HashMapT salt k v -> HashMapT salt k v
445
+ -> HashMapT salt k v
443
446
unionWithKey f = go 0
444
447
where
445
448
-- empty vs. anything
@@ -526,7 +529,7 @@ unionWithKey f = go 0
526
529
-- * Transformations
527
530
528
531
-- | /O(n)/ Transform this map by applying a function to every value.
529
- mapWithKey :: (k -> v1 -> v2 ) -> HashMap k v1 -> HashMap k v2
532
+ mapWithKey :: (k -> v1 -> v2 ) -> HashMapT salt k v1 -> HashMapT salt k v2
530
533
mapWithKey f = go
531
534
where
532
535
go Empty = Empty
@@ -538,7 +541,7 @@ mapWithKey f = go
538
541
{-# INLINE mapWithKey #-}
539
542
540
543
-- | /O(n)/ Transform this map by applying a function to every value.
541
- map :: (v1 -> v2 ) -> HashMap k v1 -> HashMap k v2
544
+ map :: (v1 -> v2 ) -> HashMapT salt k v1 -> HashMapT salt k v2
542
545
map f = mapWithKey (const f)
543
546
{-# INLINE map #-}
544
547
@@ -548,7 +551,7 @@ map f = mapWithKey (const f)
548
551
549
552
-- | /O(n)/ Transform this map by applying a function to every value
550
553
-- and retaining only some of them.
551
- mapMaybeWithKey :: (k -> v1 -> Maybe v2 ) -> HashMap k v1 -> HashMap k v2
554
+ mapMaybeWithKey :: (k -> v1 -> Maybe v2 ) -> HashMapT salt k v1 -> HashMapT salt k v2
552
555
mapMaybeWithKey f = filterMapAux onLeaf onColl
553
556
where onLeaf (Leaf h (L k v)) | Just v' <- f k v = Just (leaf h k v')
554
557
onLeaf _ = Nothing
@@ -559,7 +562,7 @@ mapMaybeWithKey f = filterMapAux onLeaf onColl
559
562
560
563
-- | /O(n)/ Transform this map by applying a function to every value
561
564
-- and retaining only some of them.
562
- mapMaybe :: (v1 -> Maybe v2 ) -> HashMap k v1 -> HashMap k v2
565
+ mapMaybe :: (v1 -> Maybe v2 ) -> HashMapT salt k v1 -> HashMapT salt k v2
563
566
mapMaybe f = mapMaybeWithKey (const f)
564
567
{-# INLINE mapMaybe #-}
565
568
@@ -578,7 +581,7 @@ mapMaybe f = mapMaybeWithKey (const f)
578
581
traverseWithKey
579
582
:: Applicative f
580
583
=> (k -> v1 -> f v2 )
581
- -> HashMap k v1 -> f (HashMap k v2 )
584
+ -> HashMapT salt k v1 -> f (HashMapT salt k v2 )
582
585
traverseWithKey f = go
583
586
where
584
587
go Empty = pure Empty
@@ -596,7 +599,7 @@ traverseWithKey f = go
596
599
-- encountered, the combining function is applied to the values of these keys.
597
600
-- If it returns 'Nothing', the element is discarded (proper set difference). If
598
601
-- it returns (@'Just' y@), the element is updated with a new value @y@.
599
- differenceWith :: (Eq k , Hashable k ) => (v -> w -> Maybe v ) -> HashMap k v -> HashMap k w -> HashMap k v
602
+ differenceWith :: (Eq k , Hashable k , KnownNat salt ) => (v -> w -> Maybe v ) -> HashMapT salt k v -> HashMapT salt k w -> HashMapT salt k v
600
603
differenceWith f a b = foldlWithKey' go empty a
601
604
where
602
605
go m k v = case HM. lookup k b of
@@ -607,8 +610,8 @@ differenceWith f a b = foldlWithKey' go empty a
607
610
-- | /O(n+m)/ Intersection of two maps. If a key occurs in both maps
608
611
-- the provided function is used to combine the values from the two
609
612
-- maps.
610
- intersectionWith :: (Eq k , Hashable k ) => (v1 -> v2 -> v3 ) -> HashMap k v1
611
- -> HashMap k v2 -> HashMap k v3
613
+ intersectionWith :: (Eq k , Hashable k , KnownNat salt ) => (v1 -> v2 -> v3 ) -> HashMapT salt k v1
614
+ -> HashMapT salt k v2 -> HashMapT salt k v3
612
615
intersectionWith f a b = foldlWithKey' go empty a
613
616
where
614
617
go m k v = case HM. lookup k b of
@@ -619,8 +622,8 @@ intersectionWith f a b = foldlWithKey' go empty a
619
622
-- | /O(n+m)/ Intersection of two maps. If a key occurs in both maps
620
623
-- the provided function is used to combine the values from the two
621
624
-- maps.
622
- intersectionWithKey :: (Eq k , Hashable k ) => (k -> v1 -> v2 -> v3 )
623
- -> HashMap k v1 -> HashMap k v2 -> HashMap k v3
625
+ intersectionWithKey :: (Eq k , Hashable k , KnownNat salt ) => (k -> v1 -> v2 -> v3 )
626
+ -> HashMapT salt k v1 -> HashMapT salt k v2 -> HashMapT salt k v3
624
627
intersectionWithKey f a b = foldlWithKey' go empty a
625
628
where
626
629
go m k v = case HM. lookup k b of
@@ -634,7 +637,7 @@ intersectionWithKey f a b = foldlWithKey' go empty a
634
637
-- | /O(n*log n)/ Construct a map with the supplied mappings. If the
635
638
-- list contains duplicate mappings, the later mappings take
636
639
-- precedence.
637
- fromList :: (Eq k , Hashable k ) => [(k , v )] -> HashMap k v
640
+ fromList :: (Eq k , Hashable k , KnownNat salt ) => [(k , v )] -> HashMapT salt k v
638
641
fromList = L. foldl' (\ m (k, ! v) -> HM. unsafeInsert k v m) empty
639
642
{-# INLINABLE fromList #-}
640
643
@@ -653,7 +656,7 @@ fromList = L.foldl' (\ m (k, !v) -> HM.unsafeInsert k v m) empty
653
656
-- > = fromList [('a', 2), ('b', 1)]
654
657
--
655
658
-- Given a list of key-value pairs @xs :: [(k, v)]@, group all values by their
656
- -- keys and return a @HashMap k [v]@.
659
+ -- keys and return a @HashMapT salt k [v]@.
657
660
--
658
661
-- > let xs = ('a', 1), ('b', 2), ('a', 3)]
659
662
-- > in fromListWith (++) [ (k, [v]) | (k, v) <- xs ]
@@ -668,7 +671,7 @@ fromList = L.foldl' (\ m (k, !v) -> HM.unsafeInsert k v m) empty
668
671
--
669
672
-- > fromListWith f [(k, a), (k, b), (k, c), (k, d)]
670
673
-- > = fromList [(k, f d (f c (f b a)))]
671
- fromListWith :: (Eq k , Hashable k ) => (v -> v -> v ) -> [(k , v )] -> HashMap k v
674
+ fromListWith :: (Eq k , Hashable k , KnownNat salt ) => (v -> v -> v ) -> [(k , v )] -> HashMapT salt k v
672
675
fromListWith f = L. foldl' (\ m (k, v) -> unsafeInsertWith f k v m) empty
673
676
{-# INLINE fromListWith #-}
674
677
@@ -698,7 +701,7 @@ fromListWith f = L.foldl' (\ m (k, v) -> unsafeInsertWith f k v m) empty
698
701
-- > = fromList [(k, f k d (f k c (f k b a)))]
699
702
--
700
703
-- @since 0.2.11
701
- fromListWithKey :: (Eq k , Hashable k ) => (k -> v -> v -> v ) -> [(k , v )] -> HashMap k v
704
+ fromListWithKey :: (Eq k , Hashable k , KnownNat salt ) => (k -> v -> v -> v ) -> [(k , v )] -> HashMapT salt k v
702
705
fromListWithKey f = L. foldl' (\ m (k, v) -> unsafeInsertWithKey f k v m) empty
703
706
{-# INLINE fromListWithKey #-}
704
707
@@ -753,6 +756,6 @@ updateOrSnocWithKey f k0 v0 ary0 = go k0 v0 ary0 0 (A.length ary0)
753
756
-- These constructors make sure the value is in WHNF before it's
754
757
-- inserted into the constructor.
755
758
756
- leaf :: Hash -> k -> v -> HashMap k v
759
+ leaf :: Hash -> k -> v -> HashMapT salt k v
757
760
leaf h k = \ ! v -> Leaf h (L k v)
758
761
{-# INLINE leaf #-}
0 commit comments