Closed
Description
We currently calculate intersections completely naively:
intersectionWithKey f a b = foldlWithKey' go empty a
where
go m k v = case lookup k b of
Just w -> insert k (f k v w) m
_ -> m
Surely we can do much better by taking advantage of the structure of a HashMap
. There are four easy cases:
intersectionWithKey :: (Eq k, Hashable k) => (k -> v1 -> v2 -> v3)
-> HashMap k v1 -> HashMap k v2 -> HashMap k v3
intersectionWithKey _ Empty !_ = Empty
intersectionWithKey _ _ Empty = Empty
intersectionWithKey f (Leaf h (L k v)) bs =
case lookup' h k bs of
Nothing -> Empty
Just vb -> Leaf h (L k (f k v vb))
intersectionWithKey f as (Leaf h (L k v)) =
case lookup' h k as of
Nothing -> Empty
Just va -> Leaf h (L k (f k va v))
We can deal with Collision
naively, or fuss about a bit to make it efficient: perform a sort of hash-only lookup in the other map to obtain a Leaf
or a Collision
, then compare all the pairs.
For BitmapIndexed
and Full
, we can first combine the bitmaps to figure out which children we even have to bother with. Pair those up and take intersections recursively. Then filter out any empties and calculate the final bitmap (I imagine this will look a lot like the nasty mapMaybeWithKey
code).