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

时间:2014-12-15 20:03:03

标签: 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)

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

顺便说一下。我知道更多&#39;像elixir一样的解决方案可能是这个(至少它能完成这项工作):

defp _span([head | tail],min,max) when head in min..max, do: [head | _span(tail,min,max)]

感谢。

2 个答案:

答案 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