在Erlang中列出累加器

时间:2014-03-05 05:25:51

标签: erlang

这是我在阅读Joe的Erlang书时找到的代码。但我无法理解。

 odds_and_evens_acc(L) ->
     odds_and_evens_acc(L, [], []).
 odds_and_evens_acc([H|T], Odds, Evens) ->
   case (H rem 2) of
       1 -> odds_and_evens_acc(T, [H|Odds], Evens);
       0 -> odds_and_evens_acc(T, Odds, [H|Evens])
   end;
 odds_and_evens_acc([], Odds, Evens) ->
   {Odds, Evens}.

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:4)

%% There are two functions - odds_and_evens_acc/1 and odds_and_evens_acc/3

%% First function. It takes a list of integers and splits it on two lists - 
%%   odds and evens. 
%% The function calls odds_and_evens_acc/3 with three arguments - 
%%   given List of integers and two empty lists which are
%%   accumulators for odds and evens. Actually they are just initial values
%%   for lists, where we store odds and evens.
odds_and_evens_acc(L) ->
     odds_and_evens_acc(L, [], []).

%% Second function. It takes 3 arguments - list of integers and initial lists for
%%   storing odds and evens. The functions works recursively. On each step it
%%   takes first element of list, test if it is odd or even, add that elemnt
%%   to appropriate list. Then function calls itself 
%%   with tail (first element deleted) of the list and lists of o/e 
%%   (one with one new element, another is the same as it was passed).
%% When the list is empty function finishes.
%%
%% Function has two clauses.
%% First clause - the list is not empty - so we should proceed.
%% Function splits it on first element (head)
%%   and reminder (tail) with pattern matching ([H|T]).
odds_and_evens_acc([H|T], Odds, Evens) ->
   %% Test head if it is odd or even.
   %% In both cases the function call itself again with the tail of the list and 
   %%   accumulators (note: head is added in appropriate accumulator). 
   case (H rem 2) of
       1 -> odds_and_evens_acc(T, [H|Odds], Evens);
       0 -> odds_and_evens_acc(T, Odds, [H|Evens])
   end;

%% Second clause. The list is empty.
%% Function finishes returning tuple with two accumulators 
%%   which are two lists, the first
%%   contains all odd elemnts of the initial list and the second - all evens.
odds_and_evens_acc([], Odds, Evens) ->
   {Odds, Evens}.

答案 1 :(得分:2)

当您尝试理解某些代码时,您可以使用调试器 - 尤其是使用非常小的代码。

编写一个名为test1.erl的文件:

-module (test1).

-compile(export_all).

odds_and_evens_acc(L) ->
     odds_and_evens_acc(L, [], []).

odds_and_evens_acc([H|T], Odds, Evens) ->
   case (H rem 2) of
       1 -> odds_and_evens_acc(T, [H|Odds], Evens);
       0 -> odds_and_evens_acc(T, Odds, [H|Evens])
   end;
odds_and_evens_acc([], Odds, Evens) ->
   {Odds, Evens}.

在同一目录下启动erlang shell:erl或werl。

1> %% compile the code for debug
1> c(test1,[debug_info]).
{ok,test1}
2> %% create a list of integer for test
2> L=lists:seq(1,8).
[1,2,3,4,5,6,7,8]
3> %% start the debugger
3> debugger:start().
{ok,<0.38.0>}
4> %% in the menu Module, select interpret... and then the file test1.erl
4> %% then check the box Auto attach on break

enter image description here

4> %% double click on module name test1
4> %% put a break point on the first line of code

enter image description here

4> %% start the function
4> test1:odds_and_evens_acc(L).

你应该到达这个窗口:

enter image description here

然后您可以使用步骤按钮并查看值面板以查看程序的演变。通过打开跟踪面板可以看到执行跟踪:选项/跟踪窗口/跟踪区域