讨论一个erlang中的模式优化级.

windywany 2009-10-21
说来真的很奇怪,一般语言的第一个语言教程都会以HELLO WORLD开始,但是ERLANG,却不是这样.我看到ERLANG的第一个程序是这样的.

 -module(test).
 -export([fac/1]).
 fac(0)->1;
 fac(N)->N*fac(N-1).


这个程序功能很简单:给出一个数值N,然后算出N*(N-1)*(N-2)*..*1.也就是N的阶乘.

这也许就是FP式语言与其它语言的差别吧.这个小小的例子中去有很大玄机啊.FP语言中的
重点:模式匹配.

在这段程序中,fac(0)->1;和fac(N)->N*fac(N-1).叫做分句.在我们调用fac时,解释器会
顺序对当前值与模式进行匹配.0与0匹配,而变量N(在erlang中以大写字母开头的字母序列叫做变量,以小字母开头的序列叫做原子(atom,姑且叫做常量吧))可以一任何值进行匹配(刚学,目前我是这么认为的).所以可不可这么说:N的模式匹配的优先级比常量(atom)的高呢?

如果我们把上面的程序改为:
 -module(test).
 -export([fac/1]).
 fac(N)->N*fac(N-1);
 fac(0)->1.


在编译(c(test).)时会有警告出现,执行时也不会得到我们想要的N的阶乘了.

欢迎大家讨论.
xinmingyao 2009-10-21
模式匹配是从上到下的,fac(N)一直匹配,所以fac(0)永远不会匹配到,程序也就没法结束了
wainwen 2009-10-25
函数语言的hello word,基本上就是阶乘
windywany 2009-10-25
wainwen 写道
函数语言的hello word,基本上就是阶乘

可否具体讲解一下?
这个例子倒是简洁,可惜不是尾递归。
bigpanda 2010-11-13
人马座阿尔法星 写道
这个例子倒是简洁,可惜不是尾递归。


加上个guard,就是尾递归了。

fact(N) when N > 0 ->
  N * fact (N-1);
fact(0) -> 1.
windywany 2010-11-15
这个guard无意义.
bigpanda 2010-11-15
windywany 写道
这个guard无意义.


为什么没意义呢?
glacjay 2010-11-25
bigpanda 写道
人马座阿尔法星 写道
这个例子倒是简洁,可惜不是尾递归。


加上个guard,就是尾递归了。

fact(N) when N > 0 ->
  N * fact (N-1);
fact(0) -> 1.



这个 guard 解决的是前面讲的顺序的问题,跟尾递归没关系,因为最后的操作不是函数调用,而是乘法。

尾递归应该是这样的:

fact(N) -> fact(N, 1).

fact(0, Acc) -> Acc;
fact(N, Acc) -> fact(N-1, N*Acc).

Hooopo 2011-09-13
glacjay 写道
bigpanda 写道
人马座阿尔法星 写道
这个例子倒是简洁,可惜不是尾递归。


加上个guard,就是尾递归了。

fact(N) when N > 0 ->
  N * fact (N-1);
fact(0) -> 1.



这个 guard 解决的是前面讲的顺序的问题,跟尾递归没关系,因为最后的操作不是函数调用,而是乘法。

尾递归应该是这样的:

fact(N) -> fact(N, 1).

fact(0, Acc) -> Acc;
fact(N, Acc) -> fact(N-1, N*Acc).


不加guardN为负值也会被匹配成功
Global site tag (gtag.js) - Google Analytics