我是功能/不可变编程的新手,我碰到了一堵墙。我试图在Elixir
中实现一个非常简单的重复数据删除功能,以重复数据删除stdin
。在Elixir的外部范围中重新绑定变量
我有使用Stream.transform/2
一个非常简单的实现,但我原来的实现中使用Stream.filter/2
这样的(这是简单化例如目的),我不知道我理解为什么它不工作:
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))
的想法显然是有一个包含读入的行,并在每个循环更新。
现在,一些调试导致我的事实hashes
里面的filter
回调在每个循环中都是空的,所以我猜它不会改变外层变量?我相信我只是想在外部重新绑定变量,而不是滤波函数中的变量。这可能吗?
我在想,我打一个范围问题,这个JavaScript作为证明(这是我能想到的唯一的比较):
var hashes = new Set();
arr.filter(function (element) {
var hashes = something(element); // i.e. using var not using outer scope
});
任何人都可以清楚地了解到是不正确上述实施?感谢提前:)
所以没有办法在外部范围重新绑定某些东西?我希望可能有办法手动这样做。 – whitfin
我认为不是。然而,这也不是惯用的。你通常不会为副作用调用函数,而是为它们的返回值。通常你使用Enum或Stream的一些函数。 'Stream.uniq/2'可以在这里和更一般的情况下工作,'Enum.reduce/3'可以做任何事情。 – manukall
原因是有Stream.filter的并行实现,但Stream.uniq没有;)谢谢你的信息。 – whitfin