用于检查范围的Elixir函数保护子句编译但不起作用

0x0*_*0me 1 elixir

在进行一些练习时,我提出了一个(可能)不是惯用的解决方案,它可以完美地编译但是没有按预期运行?

def span(xs, min, max), do: _span(xs,min,max)
defp _span([], _, _), do: []

# The following guard does not match
defp _span([head | tail],min,max) when min <= head <= max, do: [head | _span(tail,min,max)]

defp _span([head | tail],min,max), do: _span(tail,min,max)
Run Code Online (Sandbox Code Playgroud)

问题是为什么编译但不起作用?

顺便说一句.我知道'更多'类似于灵药的解决方案可能就是这个(至少它可以完成这项工作):

defp _span([head | tail],min,max) when head in min..max, do: [head | _span(tail,min,max)]
Run Code Online (Sandbox Code Playgroud)

谢谢.

sas*_*ric 8

我怀疑这个编译,因为<=是左关联的,所以a <= b <= c是相同的(a <= b) <= c.

您甚至可以在shell中验证这一点:

iex(1)> quote(do: 1 <= 2 <= 3)
{:<=, [context: Elixir, import: Kernel],
 [{:<=, [context: Elixir, import: Kernel], [1, 2]}, 3]}
Run Code Online (Sandbox Code Playgroud)

因此,1 <= 2 <= 3将达到true <= 3并且这总是false因为数字总是小于原子.