2009-11-24 57 views
4

地方为函数的条款的顺序是不重要的,是它的基础的情况下最后:在Erlang中是否有一种习惯的方法来命令函数子句?

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. 

从标准库查看源代码,它似乎这个惯例是最后的基本情况。这是首选的风格?是有原因的,还是只是它的方式?

回答

5

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

由于整数0能够匹配模式N,因此如果它出现在后面,则永远不会到达常量0子句。

这是模式匹配的有序方面,您在编写函数子句,事例子句或任何其他此类潜在匹配序列时应考虑这一点。

+0

哎呀,对不起,这是一个不好的例子,我的意思是一个函数,其中子句的排序不会改变行为。修改示例以反映这一点。 – pjb3 2009-11-24 04:31:49

4

它具有如何排序子句的语义。由于模式是按顺序尝试的。

我倾向于首先放置基本案例,因为我认为它使它更具可读性。在阅读递归部分时已经知道基本情况。

有时候我会觉得有些代码首先会将最常见的模式放在第一位,以便保存最常见的情况,从而不必测试不太可能匹配的模式。

+0

是的,我同意。首先有基本情况对我来说更有意义,但这不是标准库中的情况。在这方面出现的社区内可能没有达成共识? – pjb3 2009-11-24 04:33:23

3

随着[|][]我总是把基础案例放在第一位,而无案例最后放在第一位。我认为这更清楚,更自然。做相反的一个原因可能在于,它更类似于更一般的模式匹配,首先您可以找到更具体的案例,以便抓住它们;这里[]就像更具体的情况。只是猜测。

+0

从微观(或更确切的说是纳米)的角度来看,按预期命中率排序子句有什么好处吗?例如,我想所有()会更经常被调用非空列表而不是空列表。 – Zed 2009-11-24 07:51:05

+0

它不会受到伤害,但编译器在编译模式匹配时通常会重新排序子句。不要这样会影响当然的语义。这取决于模式的样子。 – rvirding 2009-11-26 02:05:27

相关问题