fun函式的強大用法-尾遞迴
阿新 • • 發佈:2019-01-31
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). 6 4> 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);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 rem 2==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,done 4>
注意實現尾遞迴呼叫的地方,以及呼叫的方法.
那麼沒有引數的情況也就水到渠成了:
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). true 15> P4!{echo,12}. 12 received. {echo,12} 16> P4!{echo,hello }. hello received. {echo,hello} 17> is_process_alive(P4). true 18>