Looping over Sets using Recursion

Sets (MapSet) in Elixir are implemented using Maps.
When you do this:

[1, 2, 3]
|> MapSet.new()
|> Map.to_list()

you will see, that the result is this

[__struct__: MapSet, map: %{1 => [], 2 => [], 3 => []}, version: 2]

That means, that the MapSet is just a map with some special keys (similar to Struct). That means you’re able to pattern match on the map key of the MapSet map.

So some naive implementation could be something like this:

defmodule RecursiveMapSet do
  def sum(%{map: set}) when map_size(set) == 0 do
    0
  end
  
  def sum(set) do
    {[element], rest_of_the_set} = Enum.split(set, 1)
    element + sum(MapSet.new(rest_of_the_set))
  end
end
  
set = MapSet.new([1, 2, 3])
RecursiveMapSet.sum(set) # 6

Anyway, I feel like ergonomics of lists are far better than MapSet, so I would just convert it to list, do the recursive work and then convert back to MapSet.

UPDATE: As @hauleth mentioned below, the fact that MapSet is just a Map is an implementation detail, that you should not rely on, because it can change in the future.