Pattern Matching Empty MapSets
Elixir provides MapSet
module to handle sets—lists of unique elements (shall I say “arrays” instead of lists here?). They are very handy under many circumstances. During my work on the minor update in Exvalibur
, I changed the list I mistakenly used before to be MapSet
. And there was a pitfall. Everywhere is the code I used different function clauses for empty list. But MapSet
is a module. That said, this code
@spec func(input :: list()) :: :ok | :error
def func([]), do: :error
def func([_ | _]), do: :ok
cannot be easily converted to work with MapSet
. MapSet.size/1
is an external function that cannot be used in guards. Of course one might appeal to if
as a last resort, but that’d be silly. But hey, MapSet
is a struct underneath. And it keeps the values in map
field. So yes, we still can use different clauses and guards
@spec func(input :: list()) :: :ok | :error
def func(%MapSet{map: map}) when map_size(map) == 0, do: :error
def func(%MapSet{}), do: :ok
Happy mapsetting!