Is this a bug? MapSet.to_list(MapSet.new([2,2])) == [2]

I’m learning Elixir and came up with a strange result. What I expected:
MapSet.to_list(MapSet.new([2,3])) results in [2, 3].

Not expected:
MapSet.to_list(MapSet.new([2,2])) results in [2].
Since the map has a list of identical elements I expected the result to be [2,2], not [2]. Seems MapSet.to_list converst the list to a set first and then to a list which seems inappropriate. Maybe I’m missing something.
Any clarifications/explanations welcome. Thank you!

PS. I like Erlang and was resisting the switch, now I think Elixir is my favorite language.

A set, by definition, does not have duplicate elements.

8 Likes

To add on top of @sribe’s answer: The problem does not occur in MapSet.to_list but rather in MapSet.new.
This is the function that turns the list [2, 2] into a set with only a single element:

[2,2]                #  [2,2]
|> MapSet.new()      #  #MapSet<[2]>
|> MapSet.to_list()  #  [2]

4 Likes

There is nothing wrong here, it works like it should,

2 Likes

Thank you for providing the answer. I want the set to contain whatever list is provided and eliminate duplicates at the list level, e.g. #MapSet<[2,2],[2,3],[2,2]> would be #MapSet<[2,2],[2,3]>. What is the correct way to do this in Elixir?

This can’t exist in elixir, as it violates the invariant of a set that no element exist more than once.

This what indeed would be the set that would be created from a lost that had the elements from your first invalid set.

1 Like

Since MapSet.new expects a list of elements, if your elements are themselves lists, that means that you should pass a list of lists to the function:

iex> MapSet.new([[2,2], [2,2], [2,3]])
#MapSet<[[2, 2], [2, 3]]>
4 Likes

What I meant was to add [2,2], [2,3], … and if try to add another [2,2], then it would not. Playing in iex I found the way to do that:
m = MapSet.new()
m1 = MapSet.(m, [2,2])
m1 = MapSet.put(m1, [2,3])
m1 == #MapSet<[[2, 2], [2, 3]]>
The lesson is that I cannot use MapSet.new([2,2]) to initialize the map. Have to use MapSet.put to add list elements. Or do as Qqwy just suggested. Thanks!

You’d have to wrap your element in a list if you wanted to initialise a MapSet for what you are trying to do.

iex(1)> MapSet.new [[2,2]]
#MapSet<[[2, 2]]>
2 Likes