containers
containers copied to clipboard
add Map.differenceSet
In Map.difference
the element type of the second Map
does not matter and can be chosen arbitrarily. In a current application of mine I have simply a Set
as second operand. How about adding this function:
differenceSet :: Ord k => Map k a -> Set k -> Map k a
?
There have been at least one similar suggestions some time ago (you can look it up on [email protected] if you are interested).
The "official" way of doing this is by using fromSet
to create a Map k ()
and performing the difference
.
The problem with adding this function is that once we start adding functions for combining Maps and Sets, there a multiple several candidates and the API will grow quite for little gain.
If you feel really strongly about this, you can start a discussion on [email protected] mailing list to see what is the oppinion of others.
It's this discussion thread: https://mail.haskell.org/pipermail/libraries/2012-November/018802.html
Just for the record I like to add
intersectionSet :: Ord k => Map k a -> Set k -> Map k a
partitionSet :: Ord k => Map k a -> Set k -> (Map k a, Map k a)
where partitionSet m s = (intersectionSet m s, differenceSet m s)
or more efficiently partitionSet m s = let section = intersectionSet m s in (section, difference m section)
and in IntMap
:
differenceSet :: IntMap a -> IntSet -> IntMap a
intersectionSet :: IntMap a -> IntSet -> IntMap a
partitionSet :: IntMap a -> IntSet -> (IntMap a, IntMap a)
Since the sets don't bring a
typed values with them, there seems to be no need for Key
and With
variants. At least, I have not encountered them so far.
As mentioned before, please follow the guidelines outlined on the Haskell Wiki and start the discussed on [email protected] mailing list -- all API changes of containers go through the list so that others can discuss proposed changes.
Cheers, Milan
We now have differenceSet
called withoutKeys
and intersectionSet
as restrictKeys
. The only one missing is partitionSet
, which does both at once. For Data.Map
at least, and probably also Data.IntMap
, it should be possible to get a speed boost by combining those into a custom function. But is that combination particularly important in practice? I don't know.
Another thing we could do is expand the merge interface to incorporate sets and even set/map combos. I expect this would be fairly straightforward, but I don't know how to avoid a ton of code duplication. Combining a set or map with a set or map to produce a set or map gives six different sorts of merge. Blegh! But I mention it because partitionSet
could be written as an applicative merge between a set and a map in the data Pair a = Pair a a
functor.
After having just spent some time going through the massive APIs to put together approachable docs I'm leaning towards not introducing more functions to the API that will maybe get a handful of uses :P I think that is more a point for splitting the core/internals into their own package (or just exposing the internals from containers
) and having containers
as it is today and a containers-extra
which provides the more specialized functions (but still efficient because its built on top of containers-internal`).
Today the outlined partitionSet
was the function I wanted to call (for the purposes of tracking dependencies in a program analysis task).
Is there still any opposition to adding it? It is useful to have a way to process a set of keys in one go.