在Erlang中是否有一种惯用的方法来排序函数子句?

在Erlang中是否有一种惯用的方法来排序函数子句?,erlang,Erlang,对于子句顺序不重要的函数,是否为基本情况last: all(Pred, [Head|Tail]) -> case Pred(Head) of true -> all(Pred, Tail); false -> false end; all(Pred, []) when is_function(Pred, 1) -> true. 或基本情况优先: all(Pred, []) when is_function(Pred, 1) -> true;

对于子句顺序不重要的函数,是否为基本情况last:

all(Pred, [Head|Tail]) ->
  case Pred(Head) of
    true -> all(Pred, Tail);
    false -> false
  end;
all(Pred, []) when is_function(Pred, 1) -> true.
或基本情况优先:

all(Pred, []) when is_function(Pred, 1) -> true;
all(Pred, [Head|Tail]) ->
  case Pred(Head) of
    true -> all(Pred, Tail);
    false -> false
  end.

从标准库中的源代码来看,该约定似乎是最后一个基本情况。那是你喜欢的款式吗?这是有原因的,还是仅仅是它的方式?

只有第二种情况会起作用,因为情况是按顺序匹配的

因为整数0能够匹配模式N,所以如果常量0子句位于模式N之后,则永远不会到达该子句


在编写函数子句、case子句或任何其他类似的潜在匹配序列时,您应该考虑模式匹配的有序方面。

它在语义上表示子句的有序性。因为模式是按顺序尝试的

我倾向于把基本情况放在第一位,因为我认为这会使它更具可读性。在阅读递归部分时已经知道基本情况


有时我觉得有些代码把最常见的模式放在第一位,以避免最常见的情况必须测试它不可能匹配的模式。

对于
[|]
[]
我总是把基本情况放在第一位,把零情况放在最后,就像在第一个情况一样。我认为这更清楚、更自然。做相反的事情的一个原因可能是,它更类似于更一般的模式匹配,即首先有更具体的案例,以便捕捉它们;这里的
[]
类似于更具体的情况。只是猜测而已。

哎呀,对不起,这是个糟糕的例子,我指的是一个子句的顺序不会改变行为的函数。修改了这个例子来反映这一点。是的,我同意。首先使用基本用例对我来说更有意义,但在标准库中并非如此。似乎社区内对此没有达成共识?从微观(或者说是纳米)优化的角度来看,按预期命中率排序条款有什么好处吗?例如,我假设all()在非空列表中调用的次数比在空列表中调用的次数要多。这不会有什么坏处,但编译器在编译模式匹配时经常会对子句重新排序。当然,这不会影响语义。这取决于图案的外观。