containers
containers copied to clipboard
Function for updating with default value (mostly for nested maps)
Maybe, I'm doing something wrong, but this combination is very frequent in my programms. Imagine we have some nested map
m :: Map Foo (Map Bar Baz)
and we want to insert a value baz
to the bar
of foo
. I think it would be nice to have something like
mupdate :: Monoid a => (a -> a) -> k -> Map k a -> Map k a
mupdate upd = alter (Just . upd . fromMaybe mempty)
to call this like mupdate (insert bar baz) foo
.
Maybe with upsert from #809 it will be also acceptable --- just upsert (insert bar baz . fromMaybe mempty) foo
or even there is a perfect way using currently implemented functionality, but I can't see them.
P. S. of course, this can be easily done throw non
from lens, but lens are not always advisable
Maybe you want insertWith union foo (singleton bar baz)
?
> f a b c = insertWith union a (singleton b c)
> :t f
f :: (Ord k1, Ord k2) => k1 -> k2 -> a -> Map k1 (Map k2 a) -> Map k1 (Map k2 a)
> f "0" "1" "2" mempty
fromList [("0",fromList [("1","2")])]
> f "0" "1" "2" $ singleton "0" mempty
fromList [("0",fromList [("1","2")])]
> f "0" "1" "2" $ singleton "0" $ singleton "1" ""
fromList [("0",fromList [("1","2")])]
Alternatively, see https://hackage.haskell.org/package/monoidal-containers. That should let you do nested inserts direcly
let path = singleton a $ singleton b $ singleton c $ First d
in path <> oldMap