@@ -23,15 +23,20 @@ module Data.HashMap.Monoidal
24 , notMember
24 , notMember
30import Prelude hiding (lookup)
35import Prelude hiding (lookup)
36+import Data.Maybe (fromMaybe)
31import Data.Monoid
37import Data.Monoid
32import Data.Foldable (Foldable)
38import Data.Foldable (Foldable)
33−import Data.Traversable (Traversable)
34−import Control.Applicative (Applicative, pure)
39+import Control.Applicative (pure)
35import Data.Data (Data)
40import Data.Data (Data)
36import Data.Typeable (Typeable)
41import Data.Typeable (Typeable)
@@ -96,9 +101,9 @@ instance Newtype (MonoidalHashMap k a) (M.HashMap k a) where
96 {-# INLINE unpack #-}
101 {-# INLINE unpack #-}
98#if MIN_VERSION_base(4,7,0)
103#if MIN_VERSION_base(4,7,0)
99−instance (Eq k, Hashable k) => IsList (MonoidalHashMap k a) where
104+instance (Eq k, Hashable k, Monoid a) => IsList (MonoidalHashMap k a) where
100 type Item (MonoidalHashMap k a) = (k, a)
105 type Item (MonoidalHashMap k a) = (k, a)
101− fromList = MM . M.fromList
106+ fromList = MM . M.fromListWith mappend
102 {-# INLINE fromList #-}
107 {-# INLINE fromList #-}
103 toList = M.toList . unpack
108 toList = M.toList . unpack
104 {-# INLINE toList #-}
109 {-# INLINE toList #-}
@@ -130,6 +135,12 @@ lookup :: (Eq k, Hashable k) => k -> MonoidalHashMap k v -> Maybe v
130lookup k = M.lookup k . unpack
135lookup k = M.lookup k . unpack
131{-# INLINE lookup #-}
136{-# INLINE lookup #-}
138+-- | /O(log n)/ Return the value to which the specified key is mapped,
139+-- or mempty 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 #-}
133-- | /O(log n)/. Delete a key and its value from the map. When the key is not
144-- | /O(log n)/. Delete a key and its value from the map. When the key is not
134-- a member of the map, the original map is returned.
145-- a member of the map, the original map is returned.
135delete :: (Eq k, Hashable k) => k -> MonoidalHashMap k a -> MonoidalHashMap k a
146delete :: (Eq k, Hashable k) => k -> MonoidalHashMap k a -> MonoidalHashMap k a
@@ -148,3 +159,33 @@ elems = M.elems . unpack
148keys :: MonoidalHashMap k a -> [k]
159keys :: MonoidalHashMap k a -> [k]
149keys = M.keys . unpack
160keys = M.keys . unpack
150{-# INLINE keys #-}
161{-# INLINE keys #-}
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)
167+ -> k -> MonoidalHashMap k a
168+ -> MonoidalHashMap k a
170+ . M.insertWith (\_ old -> f old) k (f mempty)
172+{-# INLINE modify #-}
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)
178+ -> k -> MonoidalHashMap k a
179+ -> MonoidalHashMap k a
180+modifyDef d f k = pack
181+ . M.insertWith (\_ old -> f old) k d
183+{-# INLINE modifyDef #-}
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
190+ . map (\(k, v) -> (f k, v))