在进行一些练习时,我提出了一个(可能)不是惯用的解决方案,它可以完美地编译但是没有按预期运行?
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)
问题是为什么要编译但不起作用?
顺便说一下。我知道更多&#39;像elixir一样的解决方案可能是这个(至少它能完成这项工作):
defp _span([head | tail],min,max) when head in min..max, do: [head | _span(tail,min,max)]
感谢。
答案 0 :(得分:8)
我怀疑这是编译因为&lt; =是关联的,所以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]}
因此,1 <= 2 <= 3
将达到true <= 3
,并且始终为false
,因为数字始终小于原子。
答案 1 :(得分:3)
它确实编译,因为你的保护条款min <= head <= max
是有效的Elixir语法。正如sasajuric所指出的,1 <= 2 <= 3
将达true <= 3
。请注意,您可以比较不同类型的数据。在Elixir中,数据类型具有如下排序顺序:
number < atom < reference < functions < port < pid < tuple < maps < list < bitstring