Skip to content

Commit 3e00ddb

Browse files
committed
Make strict build as well
1 parent bfbdb3e commit 3e00ddb

File tree

1 file changed

+44
-41
lines changed

1 file changed

+44
-41
lines changed

Data/HashMap/Internal/Strict.hs

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{-# LANGUAGE BangPatterns, CPP, PatternGuards, MagicHash, UnboxedTuples #-}
22
{-# LANGUAGE LambdaCase #-}
33
{-# LANGUAGE Trustworthy #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
45
{-# OPTIONS_HADDOCK not-home #-}
56

67
------------------------------------------------------------------------
@@ -141,6 +142,8 @@ import Data.Functor.Identity
141142
#endif
142143
import Control.Applicative (Const (..))
143144
import Data.Coerce
145+
import GHC.TypeLits(KnownNat)
146+
import Data.Proxy(Proxy(..))
144147

145148
-- $strictness
146149
--
@@ -155,7 +158,7 @@ import Data.Coerce
155158
-- * Construction
156159

157160
-- | /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
159162
singleton k !v = HM.singleton k v
160163

161164
------------------------------------------------------------------------
@@ -164,7 +167,7 @@ singleton k !v = HM.singleton k v
164167
-- | /O(log n)/ Associate the specified value with the specified
165168
-- key in this map. If this map previously contained a mapping for
166169
-- 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
168171
insert k !v = HM.insert k v
169172
{-# INLINABLE insert #-}
170173

@@ -175,11 +178,11 @@ insert k !v = HM.insert k v
175178
--
176179
-- > insertWith f k v map
177180
-- > 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
180183
insertWith f k0 v0 m0 = go h0 k0 v0 0 m0
181184
where
182-
h0 = hash k0
185+
h0 = hash (Proxy :: Proxy salt) k0
183186
go !h !k x !_ Empty = leaf h k x
184187
go h k x s t@(Leaf hy l@(L ky y))
185188
| hy == h = if ky == k
@@ -209,16 +212,16 @@ insertWith f k0 v0 m0 = go h0 k0 v0 0 m0
209212
{-# INLINABLE insertWith #-}
210213

211214
-- | 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
214217
unsafeInsertWith f k0 v0 m0 = unsafeInsertWithKey (const f) k0 v0 m0
215218
{-# INLINABLE unsafeInsertWith #-}
216219

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
219222
unsafeInsertWithKey f k0 v0 m0 = runST (go h0 k0 v0 0 m0)
220223
where
221-
h0 = hash k0
224+
h0 = hash (Proxy :: Proxy salt) k0
222225
go !h !k x !_ Empty = return $! leaf h k x
223226
go h k x s t@(Leaf hy l@(L ky y))
224227
| hy == h = if ky == k
@@ -251,10 +254,10 @@ unsafeInsertWithKey f k0 v0 m0 = runST (go h0 k0 v0 0 m0)
251254

252255
-- | /O(log n)/ Adjust the value tied to a given key in this map only
253256
-- 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
255258
adjust f k0 m0 = go h0 k0 0 m0
256259
where
257-
h0 = hash k0
260+
h0 = hash (Proxy :: Proxy salt) k0
258261
go !_ !_ !_ Empty = Empty
259262
go h k _ t@(Leaf hy (L ky y))
260263
| hy == h && ky == k = leaf h k (f y)
@@ -281,7 +284,7 @@ adjust f k0 m0 = go h0 k0 0 m0
281284
-- | /O(log n)/ The expression @('update' f k map)@ updates the value @x@ at @k@
282285
-- (if it is in the map). If @(f x)@ is 'Nothing', the element is deleted.
283286
-- 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
285288
update f = alter (>>= f)
286289
{-# INLINABLE update #-}
287290

@@ -293,7 +296,7 @@ update f = alter (>>= f)
293296
-- @
294297
-- 'lookup' k ('alter' f k m) = f ('lookup' k m)
295298
-- @
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
297300
alter f k m =
298301
case f (HM.lookup k m) of
299302
Nothing -> delete k m
@@ -309,15 +312,15 @@ alter f k m =
309312
-- <https://hackage.haskell.org/package/lens/docs/Control-Lens-At.html#v:at Control.Lens.At>.
310313
--
311314
-- @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)
314317
-- Special care is taken to only calculate the hash once. When we rewrite
315318
-- with RULES, we also ensure that we only compare the key for equality
316319
-- once. We force the value of the map for consistency with the rewritten
317320
-- version; otherwise someone could tell the difference using a lazy
318321
-- @f@ and a functor that is similar to Const but not actually Const.
319322
alterF f = \ !k !m ->
320-
let !h = hash k
323+
let !h = hash (Proxy :: Proxy salt) k
321324
mv = lookup' h k m
322325
in (<$> f mv) $ \fres ->
323326
case fres of
@@ -378,18 +381,18 @@ impossibleAdjust = error "Data.HashMap.alterF internal error: impossible adjust"
378381
--
379382
-- Failure to abide by these laws will make demons come out of your nose.
380383
alterFWeird
381-
:: (Functor f, Eq k, Hashable k)
384+
:: (Functor f, Eq k, Hashable k, KnownNat salt)
382385
=> f (Maybe v)
383386
-> 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)
385388
alterFWeird _ _ f = alterFEager f
386389
{-# INLINE [0] alterFWeird #-}
387390

388391
-- | This is the default version of alterF that we use in most non-trivial
389392
-- cases. It's called "eager" because it looks up the given key in the map
390393
-- 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)
393396
alterFEager f !k !m = (<$> f mv) $ \fres ->
394397
case fres of
395398

@@ -418,7 +421,7 @@ alterFEager f !k !m = (<$> f mv) $ \fres ->
418421
-- If the value changed, update the value.
419422
else insertKeyExists collPos h k v' m
420423

421-
where !h = hash k
424+
where !h = hash (Proxy :: Proxy salt) k
422425
!lookupRes = lookupRecordCollision h k m
423426
!mv = case lookupRes of
424427
Absent -> Nothing
@@ -431,15 +434,15 @@ alterFEager f !k !m = (<$> f mv) $ \fres ->
431434

432435
-- | /O(n+m)/ The union of two maps. If a key occurs in both maps,
433436
-- 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
436439
unionWith f = unionWithKey (const f)
437440
{-# INLINE unionWith #-}
438441

439442
-- | /O(n+m)/ The union of two maps. If a key occurs in both maps,
440443
-- 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
443446
unionWithKey f = go 0
444447
where
445448
-- empty vs. anything
@@ -526,7 +529,7 @@ unionWithKey f = go 0
526529
-- * Transformations
527530

528531
-- | /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
530533
mapWithKey f = go
531534
where
532535
go Empty = Empty
@@ -538,7 +541,7 @@ mapWithKey f = go
538541
{-# INLINE mapWithKey #-}
539542

540543
-- | /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
542545
map f = mapWithKey (const f)
543546
{-# INLINE map #-}
544547

@@ -548,7 +551,7 @@ map f = mapWithKey (const f)
548551

549552
-- | /O(n)/ Transform this map by applying a function to every value
550553
-- 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
552555
mapMaybeWithKey f = filterMapAux onLeaf onColl
553556
where onLeaf (Leaf h (L k v)) | Just v' <- f k v = Just (leaf h k v')
554557
onLeaf _ = Nothing
@@ -559,7 +562,7 @@ mapMaybeWithKey f = filterMapAux onLeaf onColl
559562

560563
-- | /O(n)/ Transform this map by applying a function to every value
561564
-- 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
563566
mapMaybe f = mapMaybeWithKey (const f)
564567
{-# INLINE mapMaybe #-}
565568

@@ -578,7 +581,7 @@ mapMaybe f = mapMaybeWithKey (const f)
578581
traverseWithKey
579582
:: Applicative f
580583
=> (k -> v1 -> f v2)
581-
-> HashMap k v1 -> f (HashMap k v2)
584+
-> HashMapT salt k v1 -> f (HashMapT salt k v2)
582585
traverseWithKey f = go
583586
where
584587
go Empty = pure Empty
@@ -596,7 +599,7 @@ traverseWithKey f = go
596599
-- encountered, the combining function is applied to the values of these keys.
597600
-- If it returns 'Nothing', the element is discarded (proper set difference). If
598601
-- 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
600603
differenceWith f a b = foldlWithKey' go empty a
601604
where
602605
go m k v = case HM.lookup k b of
@@ -607,8 +610,8 @@ differenceWith f a b = foldlWithKey' go empty a
607610
-- | /O(n+m)/ Intersection of two maps. If a key occurs in both maps
608611
-- the provided function is used to combine the values from the two
609612
-- 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
612615
intersectionWith f a b = foldlWithKey' go empty a
613616
where
614617
go m k v = case HM.lookup k b of
@@ -619,8 +622,8 @@ intersectionWith f a b = foldlWithKey' go empty a
619622
-- | /O(n+m)/ Intersection of two maps. If a key occurs in both maps
620623
-- the provided function is used to combine the values from the two
621624
-- 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
624627
intersectionWithKey f a b = foldlWithKey' go empty a
625628
where
626629
go m k v = case HM.lookup k b of
@@ -634,7 +637,7 @@ intersectionWithKey f a b = foldlWithKey' go empty a
634637
-- | /O(n*log n)/ Construct a map with the supplied mappings. If the
635638
-- list contains duplicate mappings, the later mappings take
636639
-- 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
638641
fromList = L.foldl' (\ m (k, !v) -> HM.unsafeInsert k v m) empty
639642
{-# INLINABLE fromList #-}
640643

@@ -653,7 +656,7 @@ fromList = L.foldl' (\ m (k, !v) -> HM.unsafeInsert k v m) empty
653656
-- > = fromList [('a', 2), ('b', 1)]
654657
--
655658
-- 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]@.
657660
--
658661
-- > let xs = ('a', 1), ('b', 2), ('a', 3)]
659662
-- > in fromListWith (++) [ (k, [v]) | (k, v) <- xs ]
@@ -668,7 +671,7 @@ fromList = L.foldl' (\ m (k, !v) -> HM.unsafeInsert k v m) empty
668671
--
669672
-- > fromListWith f [(k, a), (k, b), (k, c), (k, d)]
670673
-- > = 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
672675
fromListWith f = L.foldl' (\ m (k, v) -> unsafeInsertWith f k v m) empty
673676
{-# INLINE fromListWith #-}
674677

@@ -698,7 +701,7 @@ fromListWith f = L.foldl' (\ m (k, v) -> unsafeInsertWith f k v m) empty
698701
-- > = fromList [(k, f k d (f k c (f k b a)))]
699702
--
700703
-- @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
702705
fromListWithKey f = L.foldl' (\ m (k, v) -> unsafeInsertWithKey f k v m) empty
703706
{-# INLINE fromListWithKey #-}
704707

@@ -753,6 +756,6 @@ updateOrSnocWithKey f k0 v0 ary0 = go k0 v0 ary0 0 (A.length ary0)
753756
-- These constructors make sure the value is in WHNF before it's
754757
-- inserted into the constructor.
755758

756-
leaf :: Hash -> k -> v -> HashMap k v
759+
leaf :: Hash -> k -> v -> HashMapT salt k v
757760
leaf h k = \ !v -> Leaf h (L k v)
758761
{-# INLINE leaf #-}

0 commit comments

Comments
 (0)