Skip to content

Commit 339866b

Browse files
authored
add mapKeys (#308)
* add mapKeys * use doctest-style for examples in comments * document the unexpected behaviour of mapKeys in case of conflicting keys * reword documentation for mapKeys
1 parent 10328f2 commit 339866b

File tree

5 files changed

+24
-0
lines changed

5 files changed

+24
-0
lines changed

Data/HashMap/Internal.hs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ module Data.HashMap.Internal
6767
, map
6868
, mapWithKey
6969
, traverseWithKey
70+
, mapKeys
7071

7172
-- * Difference and intersection
7273
, difference
@@ -1751,6 +1752,22 @@ traverseWithKey f = go
17511752
Collision h <$> A.traverse' (\ (L k v) -> L k <$> f k v) ary
17521753
{-# INLINE traverseWithKey #-}
17531754

1755+
-- | /O(n)/.
1756+
-- @'mapKeys' f s@ is the map obtained by applying @f@ to each key of @s@.
1757+
--
1758+
-- The size of the result may be smaller if @f@ maps two or more distinct
1759+
-- keys to the same new key. In this case there is no guarantee which of the
1760+
-- associated values is chosen for the conflicting key.
1761+
--
1762+
-- >>> mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])
1763+
-- fromList [(4,"b"),(6,"a")]
1764+
-- >>> mapKeys (\ _ -> 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")])
1765+
-- fromList [(1,"c")]
1766+
-- >>> mapKeys (\ _ -> 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")])
1767+
-- fromList [(3,"c")]
1768+
mapKeys :: (Eq k2, Hashable k2) => (k1 -> k2) -> HashMap k1 v -> HashMap k2 v
1769+
mapKeys f = fromList . foldrWithKey (\k x xs -> (f k, x) : xs) []
1770+
17541771
------------------------------------------------------------------------
17551772
-- * Difference and intersection
17561773

Data/HashMap/Internal/Strict.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ module Data.HashMap.Internal.Strict
8181
, map
8282
, mapWithKey
8383
, traverseWithKey
84+
, mapKeys
8485

8586
-- * Difference and intersection
8687
, difference

Data/HashMap/Lazy.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ module Data.HashMap.Lazy
6666
, map
6767
, mapWithKey
6868
, traverseWithKey
69+
, mapKeys
6970

7071
-- * Difference and intersection
7172
, difference

Data/HashMap/Strict.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module Data.HashMap.Strict
6565
, map
6666
, mapWithKey
6767
, traverseWithKey
68+
, mapKeys
6869

6970
-- * Difference and intersection
7071
, difference

tests/HashMapProperties.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@ pTraverse xs =
301301
L.sort (fmap (L.sort . M.toList) (M.traverseWithKey (\_ v -> [v + 1, v + 2]) (M.fromList (take 10 xs))))
302302
== L.sort (fmap (L.sort . HM.toList) (HM.traverseWithKey (\_ v -> [v + 1, v + 2]) (HM.fromList (take 10 xs))))
303303

304+
pMapKeys :: [(Int, Int)] -> Bool
305+
pMapKeys = M.mapKeys (+1) `eq_` HM.mapKeys (+1)
306+
304307
------------------------------------------------------------------------
305308
-- ** Difference and intersection
306309

@@ -504,6 +507,7 @@ tests =
504507
-- Transformations
505508
, testProperty "map" pMap
506509
, testProperty "traverse" pTraverse
510+
, testProperty "mapKeys" pMapKeys
507511
-- Folds
508512
, testGroup "folds"
509513
[ testProperty "foldr" pFoldr

0 commit comments

Comments
 (0)