fun函数的强大用法-尾递归

来源:互联网 发布:怎样在淘宝兼职 编辑:程序博客网 时间:2024/06/07 13:57
List Comprehensions的更是强大,官方文档:http://www.erlang.org/doc/programming_examples/list_comprehensions.html另外列表解析可以在Erlang Shell中方便的实现for循环和if
 


但是在Erlang Shell里面怎么写尾递归呢?
1>  Fun =fun(X)  when X rem 2==0 ->X; (X) -> X+1 end .#Fun<erl_eval.6.13229925>2>  F1 =fun(X)  when X rem 2==0 ->X; (X) -> (X+1) end .#Fun<erl_eval.6.13229925>3> F1(5).64>  F2 =fun(X)  when X rem 2==0 ->X; (X) -> (X+7) end .#Fun<erl_eval.6.13229925>5> F2(5).12
可以看到在一个参数的时候,上面的代码是可以的,啊哈,不错,那两个参数的情况是不是正常呢?
6> F3 = fun(X,Y) when Y<1000 ->io:format("~p,",[X+Y]), (Y,X+Y); (X,Y)-> done end.
* 1: syntax error before: ','

7> F3 = fun(X,Y) when Y<1000 ->io:format("~p,",[X+Y]), (Y,X+Y); (X,Y)-> done end.
* 1: syntax error before: ','

8> F1 =fun(X,Y) when X rem2==0 ->{X,Y}; (X) -> (X+7,Y) end .
* 1: syntax error before: ','

7>

结果让人失望,会有语法错误,那没有参数的情况呢
如果要达到我们的目标,要把尾递归要执行的当前方法作为参数传进去,几番折腾,终于搞出来了:
8>  F7 = fun(F,X,Y) when Y<1000 ->io:format("~p,",[X+Y]), F(F,Y,X+Y); (F,X,Y)->done end.#Fun<erl_eval.18.105910772>
马上写一个有意义的demo出来看看,输出一下斐波那契数列吧
1> Func = fun(F, X,Y) when Y<10000 ->io:format("~p,",[X+Y]), F(F,Y,X+Y); (F,X,Y)-> done end.#Fun<erl_eval.18.105910772>2> Func(Func,0,1).1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,done4>
 注意实现尾递归调用的地方,以及调用的方法.
 那么没有参数的情况也就水到渠成了:
12>  Fn= fun(F)-> receive {echo,Msg} -> io:format("~p received.~n",[Msg]),F(F);stop-> stop end end.#Fun<erl_eval.6.13229925>13> P4=spawn(fun() -> Fn(Fn) end).<0.48.0>14> is_process_alive(P4).true15> P4!{echo,12}.12 received.{echo,12}16> P4!{echo,hello }.hello received.{echo,hello}17> is_process_alive(P4).true18>
 
http://stackoverflow.com/questions/867418/how-do-you-write-a-fun-thats-recursive-in-erlang/867525