内核.--/2奇怪的行为

Ale*_*kin 6 elixir

请考虑以下代码:

iex|1 ? [:foo, :bar] -- [:foo, :bar]
#? []
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但:

iex|2 ? [:foo, :bar] -- [] -- [:foo, :bar]
#? [:foo, :bar]
Run Code Online (Sandbox Code Playgroud)

更重要的是,它不是从右到左:

iex|3 ? [:foo, :bar] -- [:foo] -- [:foo, :bar] 
#? [:foo, :bar]

iex|4 ? IO.inspect([:foo, :bar], label: "1") --
...|4 ?   IO.inspect([:foo], label: "2") --
...|4 ?   IO.inspect([:foo, :bar], label: "3")
#? 1: [:foo, :bar]
#  2: [:foo]
#  3: [:foo, :bar]

#? [:foo, :bar]
Run Code Online (Sandbox Code Playgroud)

我错过了一些明显的东西吗 这里发生了什么?不应该有任何魔力,因为Kernel.--/2只是委托给:erlang.--(left, right).

为什么连续减去列表导致noop?


FWIW,带括号的一切都按预期工作:

iex|5 ? ([:foo, :bar] -- [:foo]) -- [:foo, :bar]
#? []
Run Code Online (Sandbox Code Playgroud)

更多乐趣:

iex|6 ? [:foo, :bar] -- [:foo] -- []  
#? [:bar]
iex|7 ? [:foo, :bar] -- [:foo] -- [:foo]
#? [:foo, :bar]
iex|8 ? [:foo, :bar] -- [:foo] -- [:bar]
#? [:bar]
Run Code Online (Sandbox Code Playgroud)

后续调查结果.短语缩减以某种方式设法遵循右关联语义:

Enum.reduce([[:foo, :bar], [:foo], [:foo, :bar]], &Kernel.--/2)
#? [:foo, :bar]
Run Code Online (Sandbox Code Playgroud)

但是具有明确功能的完整格式的却没有

Enum.reduce(
  [[:foo, :bar], [:foo], [:foo, :bar]],
  fn e, acc -> acc -- e end
)
#? []
Run Code Online (Sandbox Code Playgroud)

Mát*_*áté 5

++并且--右关联操作.你的初始代码:

[:foo, :bar] -- [:foo] -- [:foo, :bar]
Run Code Online (Sandbox Code Playgroud)

实际上被评估为

[:foo, :bar] -- ([:foo] -- [:foo, :bar])
Run Code Online (Sandbox Code Playgroud)

当您取括号中的内容时:从中删除元素[:foo]列表,删除的列表包含原始列表([:foo]),因此评估为空列表[].

然后从最左边的列表中删除此空列表:

[:foo, :bar] -- []
Run Code Online (Sandbox Code Playgroud)

这让你得到了结果[:foo, :bar].