我是功能/不可變編程的新手,我碰到了一堵牆。我試圖在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