diff --git a/Data/HashMap/Internal.hs b/Data/HashMap/Internal.hs index 86ac380f..f4e7d7ee 100644 --- a/Data/HashMap/Internal.hs +++ b/Data/HashMap/Internal.hs @@ -67,6 +67,7 @@ module Data.HashMap.Internal , map , mapWithKey , traverseWithKey + , mapKeys -- * Difference and intersection , difference @@ -1751,6 +1752,22 @@ traverseWithKey f = go Collision h <$> A.traverse' (\ (L k v) -> L k <$> f k v) ary {-# INLINE traverseWithKey #-} +-- | /O(n)/. +-- @'mapKeys' f s@ is the map obtained by applying @f@ to each key of @s@. +-- +-- The size of the result may be smaller if @f@ maps two or more distinct +-- keys to the same new key. In this case there is no guarantee which of the +-- associated values is chosen for the conflicting key. +-- +-- >>> mapKeys (+ 1) (fromList [(5,"a"), (3,"b")]) +-- fromList [(4,"b"),(6,"a")] +-- >>> mapKeys (\ _ -> 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) +-- fromList [(1,"c")] +-- >>> mapKeys (\ _ -> 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) +-- fromList [(3,"c")] +mapKeys :: (Eq k2, Hashable k2) => (k1 -> k2) -> HashMap k1 v -> HashMap k2 v +mapKeys f = fromList . foldrWithKey (\k x xs -> (f k, x) : xs) [] + ------------------------------------------------------------------------ -- * Difference and intersection diff --git a/Data/HashMap/Internal/Strict.hs b/Data/HashMap/Internal/Strict.hs index f1239864..b94cbe34 100644 --- a/Data/HashMap/Internal/Strict.hs +++ b/Data/HashMap/Internal/Strict.hs @@ -81,6 +81,7 @@ module Data.HashMap.Internal.Strict , map , mapWithKey , traverseWithKey + , mapKeys -- * Difference and intersection , difference diff --git a/Data/HashMap/Lazy.hs b/Data/HashMap/Lazy.hs index e238eb2c..cbe1d462 100644 --- a/Data/HashMap/Lazy.hs +++ b/Data/HashMap/Lazy.hs @@ -66,6 +66,7 @@ module Data.HashMap.Lazy , map , mapWithKey , traverseWithKey + , mapKeys -- * Difference and intersection , difference diff --git a/Data/HashMap/Strict.hs b/Data/HashMap/Strict.hs index ce12a6f7..0ba674ec 100644 --- a/Data/HashMap/Strict.hs +++ b/Data/HashMap/Strict.hs @@ -65,6 +65,7 @@ module Data.HashMap.Strict , map , mapWithKey , traverseWithKey + , mapKeys -- * Difference and intersection , difference diff --git a/tests/HashMapProperties.hs b/tests/HashMapProperties.hs index e9bcf19c..77879146 100644 --- a/tests/HashMapProperties.hs +++ b/tests/HashMapProperties.hs @@ -301,6 +301,9 @@ pTraverse xs = L.sort (fmap (L.sort . M.toList) (M.traverseWithKey (\_ v -> [v + 1, v + 2]) (M.fromList (take 10 xs)))) == L.sort (fmap (L.sort . HM.toList) (HM.traverseWithKey (\_ v -> [v + 1, v + 2]) (HM.fromList (take 10 xs)))) +pMapKeys :: [(Int, Int)] -> Bool +pMapKeys = M.mapKeys (+1) `eq_` HM.mapKeys (+1) + ------------------------------------------------------------------------ -- ** Difference and intersection @@ -504,6 +507,7 @@ tests = -- Transformations , testProperty "map" pMap , testProperty "traverse" pTraverse + , testProperty "mapKeys" pMapKeys -- Folds , testGroup "folds" [ testProperty "foldr" pFoldr