Open
Description
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