I'm new to functional/immutable programming and I've hit a wall. I'm trying to implement a very simply deduplication function in Elixir
to deduplicate stdin
.
I have a very trivial implementation using Stream.transform/2
but my original implementation used Stream.filter/2
like this (this is dumbed down for example purposes) and I'm not sure I understand why it's not working:
hashes = HashSet.new
IO.stream(:stdio, :line)
|> Stream.filter(fn(line) ->
if HashSet.member?(hashes, line) do
false
else
hashes = HashSet.put(hashes, line)
true
end
end)
|> Enum.each(&IO.write(&1))
The idea is clearly that there's a Set containing the lines read in, and it's updated on each loop.
Now, some debugging led me to the fact that hashes
inside the filter
callback is empty on each loop, so I guess it's not changing the outer variable? I believe I just want to rebind the variable on the outside, rather than the one inside the filter function. Is this possible?
I'm thinking that I'm hitting a scoping issue as demonstrated by this JavaScript (it's the only comparison I can think of):
var hashes = new Set();
arr.filter(function (element) {
var hashes = something(element); // i.e. using var not using outer scope
});
Can anybody clarify exactly what is incorrect with the above implementation? Thanks in advance :)