2014-03-05 2 views
2

다음은 Joe 's Erlang 책을 읽는 동안 찾은 코드입니다. 그러나 나는 이해할 수 없다.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}. 

도와주세요.

답변

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}. 
+0

%%. never less를 피하면 대답이 더욱 아름답습니다. –

2

일부 코드를 이해하려고 할 때 디버거를 사용할 수 있습니다. 특히 이와 같은 코드는 매우 작습니다. ERL 또는 werl : 얼랑 쉘을 시작

-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}. 

같은 디렉토리에 :

라는 파일 test1.erl를 작성합니다.

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

다음 단계 단추를 사용하여 값 패널을 살펴보고 프로그램의 진화를 볼 수 있습니다. 트레이스 패널을 열면 실행 추적을 볼 수 있습니다 : Options/Trace Window/Trace Area