Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set difference and union in one #944

Open
noughtmare opened this issue Apr 7, 2023 · 4 comments
Open

Set difference and union in one #944

noughtmare opened this issue Apr 7, 2023 · 4 comments

Comments

@noughtmare
Copy link

Set difference and union sometimes have to be computed together, such as in semi-naive fixed point computation:

seminaive :: Ord a => Set a -> (Set a -> Set a) -> Set a
seminaive x f = go Set.empty x where
  go !done !todo
    | Set.null todo' = done
    | otherwise = go (done `Set.union` todo') (f todo')
    where todo' = todo Set.\\ done

If there was a combined operation:

differenceAndUnion :: Ord a => Set a -> Set a -> (Set a, Set a)

Then I can write it more efficiently:

seminaive :: Ord a => Set a -> (Set a -> Set a) -> Set a
seminaive x f = go Set.empty x where
  go !done !todo
    | Set.null dif = uni
    | otherwise = go uni (f dif)
    where (dif, uni) = Set.differenceAndUnion todo done
@konsumlamm
Copy link
Contributor

This feels way too specialized. Most combinations of operations can probably be implemented more efficiently by having a combined operation, but that doesn't mean we should do it. This isn't something I'd expect any library to implement, on the contrary, I'd feel like this would be bloat.

@treeowl
Copy link
Contributor

treeowl commented Apr 7, 2023

I've been wanting to make an equivalent of the Data.Map mergeA interface for sets for a long time, but I've never gotten around to it. That would include this operation.

@noughtmare
Copy link
Author

noughtmare commented Apr 7, 2023

@treeowl that sounds much better than what I proposed here!

Which applicative would you use? I believe the straightforward Writer (Set a) wouldn't have the right time complexity, or would it?

@treeowl
Copy link
Contributor

treeowl commented Apr 7, 2023

I'd think

data Pair a = Pair a a

We'd have to make sure it generated good code in typical cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants