Erlang索引子句是如何处理的?

ult*_*ewb 5 indexing erlang clause

我来自Prolog背景.Prolog通常对谓词的第一个参数进行索引(大多数体面的系统允许你改变它,对多个参数进行索引等).无论如何,了解引擎索引子句如何允许您安排参数和谓词以获得更好的性能.

我最近在Erlang编写了一些代码,但是没有看到有关它如何索引子句头的任何信息,以及我应该如何安排参数和子句.谁知道?

谢谢.

rvi*_*ing 12

Erlang从左到右,对任何深度和所有类型的所有参数都进行索引.我们使用的基本算法在Simon Peyton Jones 的"函数编程语言的实现"中进行了描述,并修改了它以适应Erlang处理类型的方式.这是一本好书,即使它现在有点老了,对我来说真正的AHA体验.

这意味着没有必要重新排序参数以尝试优化模式匹配,至少不是速度.保持一致和清晰要好得多,这就是如何做到的,是否有一种惯用的方式在Erlang中命令函数参数?.这意味着代码没有问题,例如:

foo(X, [{a,A}|Rest], ...) -> ... ;
foo(X, [{b,B}|Rest], ...) -> ... ;
foo(X, [{c,C}|Rest], ...) -> ... ;
foo(X, [{d,D}|Rest], ...) -> ... ;
...
Run Code Online (Sandbox Code Playgroud)

通过将其分解为嵌套case表达式,从来没有必要尝试"帮助"编译器,它通常会更糟.这样做的唯一原因是它可以使代码更清晰地显示您的意图.

如果您确实想尝试优化模式匹配,请尝试重新排序子句,以便将文字出现的所有情况捆绑在一起.例如:

foo(1, ...) -> ... ;
foo(2, ...) -> ... ;
foo(7, ...) -> ... ;
foo(8, ...) -> ... ;
foo(I, ...) when is_integer(I), I >= 3, I =< 6 ->
    ... .
Run Code Online (Sandbox Code Playgroud)

比...更好

foo(1, ...) -> ... ;
foo(2, ...) -> ... ;
foo(I, ...) when is_integer(I), I >= 3, I =< 6 ->
    ... ;
foo(7, ...) -> ... ;
foo(8, ...) -> ... .
Run Code Online (Sandbox Code Playgroud)

索引会更好,但同样不要过度,因为差异不是很大,请保持清晰.这在任何深度都有效,例如在第一个代码示例中,列表中的元组的第一个元素.

其中大部分都是功能语言的标准配置.