Hi all,
Thanks for the responses. I want to go through and make sure I understand these.
--------------------------------------------------------
First, Henning, won't both of these allocate in proportion to the size of the map?
Map.foldrWithKey (\k a -> f k a >>) (return ())
Foldable.sequence_ . Map.mapWithKey f
In particular, will the compiler be able to avoid allocating when building up that large monadic computation in the foldrWithKey?
--------------------------------------------------------
Edward said to use foldMapWithKey, which hasn't been released yet, but it sounds like it will be.
Even then, I might argue it is somewhat non-obvious to the programmers how to use this to do a non-allocating "for-each". For example, I am not totally clear on what will happen with that tree of mappend calls -- will it allocate thunks? Further, IO is not a monoid, so am I to create an instance of "Monoid (IO ())" in order to use foldMapWithKey to iterate over the Map?
--------------------------------------------------------
That function looks more overloaded than the traverse in Data.Map that I'm referring to, e.g. here:
I'm afraid I don't understand the proposal then -- is it to use lens somehow? For the traversal I need to do over a Data.Map.Map, I need to fix 't' to be IO or Par or whatever I'm working with, so that the (k -> a -> t b) function I'm passing in can do the effects I need.
To be specific I'm proposing providing these variants:
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)
traverseWithKey_ :: Applicative t => (k -> a -> t ()) -> Map k a -> t ()
And without exposing the latter natively, I still don't understand how to trick the former into not allocating, if that's the proposal.
-Ryan