名單

這裡是列表型別最簡單的遞迴函式。此功能僅從開始到結束導航到列表,不再執行任何操作。

-spec loop(list()) -> ok.
loop([]) ->
  ok;
loop([H|T]) ->
  loop(T).

你可以這樣稱呼它:

loop([1,2,3]). % will return ok.

這裡的遞迴函式擴充套件:

loop([1|2,3]) ->
  loop([2|3]) ->
    loop([3|]) ->
      loop([]) ->
        ok.

使用 IO 操作的遞迴迴圈

以前的程式碼什麼都不做,而且沒用。因此,我們現在將建立一個執行某些操作的遞迴函式。此程式碼類似於 lists:foreach/2

-spec loop(list(), fun()) -> ok.
loop([], _) ->
  ok;
loop([H|T], Fun) 
  when is_function(Fun) ->
    Fun(H),
    loop(T, Fun).

你可以像這樣呼叫它:

Fun = fun(X) -> io:format("~p", [X]) end.
loop([1,2,3]).

這裡的遞迴函式擴充套件:

loop([1|2,3], Fun(1)) ->
  loop([2|3], Fun(2)) ->
    loop([3|], Fun(3)) ->
      loop([], _) ->
        ok.

你可以比較 lists:foreach/2 輸出:

lists:foreach(Fun, [1,2,3]).

遞迴迴圈列表返回修改後的列表

另一個有用的例子,類似於 lists:map/2 。此函式將採用一個列表和一個匿名函式。每次匹配列表中的值時,我們都會對其應用函式。

-spec loop(A::list(), fun()) -> list().
loop(List, Fun) 
  when is_list(List), is_function(Fun) ->
    loop(List, Fun, []).

-spec loop(list(), fun(), list()) -> list() | {error, list()}.
loop([], _, Buffer) 
  when is_list(Buffer) ->
    lists:reverse(Buffer);
loop([H|T], Fun, Buffer) 
  when is_function(Fun), is_list(Buffer) ->
    BufferReturn = [Fun(H)] ++ Buffer,
    loop(T, Fun, BufferReturn).

你可以這樣稱呼它:

Fun(X) -> X+1 end.
loop([1,2,3], Fun).

這裡的遞迴函式擴充套件:

loop([1|2,3], Fun(1), [2]) ->
  loop([2|3], Fun(2), [3,2]) ->
    loop([3|], Fun(3), [4,3,2]) ->
      loop([], _, [4,3,2]) ->
        list:reverse([4,3,2]) ->
          [2,3,4].

這個函式也稱為尾遞迴函式,因為我們使用像累加器這樣的變數來通過多個執行上下文傳遞修改過的資料。