
Hi all, After working on optimizing the folds defined in Data.Map, I'm not sure that the current definitions are correct. In particular, `fold` is defined as -- | /O(n)/. Fold the values in the map, such that -- @'fold' f z == 'Prelude.foldr' f z . 'elems'@. -- For example, -- -- > elems map = fold (:) [] map -- -- > let f a len = len + (length a) -- > fold f 0 (fromList [(5,"a"), (3,"bbb")]) == 4 It's not true that fold f z == foldr f z . elems in general. It only holds if `z` is an identity for `f` as `z` is used at every leaf in the tree. Using a none identity element for `z` doesn't really work in practice as a user cannot tell how many times `z` will be used, as it depends on the shape of tree which in turn depends on how balanced it is at any given point. Is there a better way to define folds over maps or should we just change the documentation to say that you most likely want `z` to be an identity? Cheers, Johan

Johan Tibell
It's not true that
fold f z == foldr f z . elems
in general. It only holds if `z` is an identity for `f` as `z` is used at every leaf in the tree.
Hey Johan,
-- | /O(n)/. Post-order fold.
foldr :: (k -> a -> b -> b) -> b -> Map k a -> b
foldr _ z Tip = z
foldr f z (Bin _ kx x l r) = foldr f (f kx x (foldr f z r)) l
Note the third parameter to the recursive foldr call -- the "z" you see
at the Tips is not the same "z" that was originally passed in.
G.
--
Gregory Collins

On Mon, Aug 23, 2010 at 11:40 AM, Gregory Collins
Johan Tibell
writes: It's not true that
fold f z == foldr f z . elems
in general. It only holds if `z` is an identity for `f` as `z` is used at every leaf in the tree.
Hey Johan,
-- | /O(n)/. Post-order fold. foldr :: (k -> a -> b -> b) -> b -> Map k a -> b foldr _ z Tip = z foldr f z (Bin _ kx x l r) = foldr f (f kx x (foldr f z r)) l
Note the third parameter to the recursive foldr call -- the "z" you see at the Tips is not the same "z" that was originally passed in.
You're of course right. I can get back to my optimizing. :)
participants (2)
-
Gregory Collins
-
Johan Tibell