containers icon indicating copy to clipboard operation
containers copied to clipboard

add Map.differenceSet

Open amigalemming opened this issue 9 years ago • 8 comments

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

?

amigalemming avatar Jun 11 '15 19:06 amigalemming

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.

foxik avatar Jun 11 '15 19:06 foxik

It's this discussion thread: https://mail.haskell.org/pipermail/libraries/2012-November/018802.html

amigalemming avatar Jun 12 '15 01:06 amigalemming

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.

amigalemming avatar Jan 14 '16 11:01 amigalemming

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

foxik avatar Jan 15 '16 08:01 foxik

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.

treeowl avatar Dec 29 '17 01:12 treeowl

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.

treeowl avatar Dec 29 '17 01:12 treeowl

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`).

m-renaud avatar Dec 29 '17 03:12 m-renaud

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.

sergv avatar Oct 13 '23 23:10 sergv