@@ -23,15 +23,20 @@ module Data.HashMap.Monoidal
2323 , member
2424 , notMember
2525 , lookup
26+ , lookupM
2627 , elems
2728 , keys
29+ , delete
30+ , mapKeys
31+ , modify
32+ , modifyDef
2833 ) where
2934
3035import Prelude hiding (lookup)
36+import Data.Maybe (fromMaybe)
3137import Data.Monoid
3238import Data.Foldable (Foldable)
33−import Data.Traversable (Traversable)
34−import Control.Applicative (Applicative, pure)
39+import Control.Applicative (pure)
3540import Data.Data (Data)
3641import Data.Typeable (Typeable)
3742
@@ -130,6 +135,12 @@ lookup :: (Eq k, Hashable k) => k -> MonoidalHashMap k v -> Maybe v
130135lookup k = M.lookup k . unpack
131136{-# INLINE lookup #-}
132137
138+-- | /O(log n)/ Return the value to which the specified key is mapped,
139+-- or 'Nothing' if this map contains no mapping for the key.
140+lookupM :: (Eq k, Hashable k, Monoid v) => k -> MonoidalHashMap k v -> v
141+lookupM k = fromMaybe mempty . M.lookup k . unpack
142+{-# INLINE lookupM #-}
143+
133144-- | /O(log n)/. Delete a key and its value from the map. When the key is not
134145-- a member of the map, the original map is returned.
135146delete :: (Eq k, Hashable k) => k -> MonoidalHashMap k a -> MonoidalHashMap k a
@@ -148,3 +159,33 @@ elems = M.elems . unpack
148159keys :: MonoidalHashMap k a -> [k]
149160keys = M.keys . unpack
150161{-# INLINE keys #-}
162+
163+-- | /O(log n)/. Modify a value on some key with a function, if value
164+-- under key doesn't exist -- use mempty.
165+modify :: (Monoid a, Hashable k, Eq k)
166+ => (a -> a)
167+ -> k -> MonoidalHashMap k a
168+ -> MonoidalHashMap k a
169+modify f k = pack
170+ . M.insertWith (\_ old -> f old) k mempty
171+ . unpack
172+{-# INLINE modify #-}
173+
174+-- | /O(log n)/. Modify a value on some key with a function, providing
175+-- a default value if that key doesn't exist.
176+modifyDef :: (Monoid a, Hashable k, Eq k)
177+ => a -> (a -> a)
178+ -> k -> MonoidalHashMap k a
179+ -> MonoidalHashMap k a
180+modifyDef d f k = pack
181+ . M.insertWith (\_ old -> f old) k d
182+ . unpack
183+{-# INLINE modifyDef #-}
184+
185+-- | /O(n)/. Map a function to each key of a map
186+mapKeys :: (Monoid a, Hashable k, Eq k, Hashable k', Eq k')
187+ => (k -> k') -> MonoidalHashMap k a
188+ -> MonoidalHashMap k' a
189+mapKeys f = fromList
190+ . map (\(k, v) -> (f k, v))
191+ . toList