I have a list of MapSets, and I want to find the intersection of all of 
them. When I’ve wanted to find the union of a list of MapSets, it’s felt 
natural to use Enum.reduce:

Enum.reduce(list_of_sets, MapSet.new, &MapSet.union/2)

To find the intersection of a list of MapSets, I wanted to use the same 
technique:

Enum.reduce(list_of_sets, MapSet.new, &MapSet.intersection/2)

…but that does not work, because the intersection of an empty set with 
another set is the empty set — so this reduction will always produce the 
empty set, regardless of what list_of_sets is. In fact, the starting 
accumulator you need is the union of all the given sets. But of course, 
that would be an inefficient way to go about it, as you’d reduce the list 
twice (once to compute the union, then again to compute the intersection, 
using the union as the initial accumulator). Instead, you should use a 
different technique:

[initial_set | rest] = list_of_setsEnum.reduce(rest, initial_set, 
&MapSet.intersection/2)

While that’s not too bad, it took me some time to figure out why my initial 
reduction attempt did not work, and there’s no simple way to provide an 
initial accumulator that lets you reduce over the whole list.

One solution would be to introduce MapSet.intersection/1. Given an 
enumerable of sets, it would compute the intersection of all of them. This 
is similar to the fact that we have both Enum.concat/2 (which concats two 
lists), and Enum.concat/1 (which, given an enumerable of enumerables, 
concats them in to a single list). If we introduce MapSet.intersection/1, 
we may also want MapSet.union/1 for parity.

Thoughts?
Myron
​

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/924446b6-9a96-4eb0-8ba4-2d47509190f3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to