Skip to content

New convenience function for Data.Map #784

@nmichael44

Description

@nmichael44

Consider inserting (k, v) elements into a map (Data.Map) in a
scenario where if the element exists you want to combine the new
element (v) with the old existing element. For this we have function:

insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

which does the trick.

But consider this scenario:

m : Map Key [Values]

and when we insert we want to add another value to the list if the key
is there.

We now have to do:

insertWith (++) k [newV] m

So we need to build a new singleton list and then call append from
every insert. The suggestion is to add a new function in which we
parametrize more generally over the value of the map as below.

insertWith' :: Ord k => (a -> m a -> m a) -> (a -> m a) -> k -> a
                        -> M.Map k (m a) -> M.Map k (m a)

The behavior we want is the following but without the double tree
traversal (2*log(n)) cost.

insertWith' f g k a m
  = M.insert
             k
             (case M.lookup k m of
                Nothing -> g a
                Just ma -> f a ma)
             m

With such a function for the example above we could then do:

insertWith' (:) (: []) k a m

and so avoid creating the singleton lists. Of course this is not specific to lists... it would help with any container value in the position of map value.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions