[erlang-questions] Accumulators..

Ryan Zezeski rzezeski@REDACTED
Tue Oct 26 05:30:56 CEST 2010


On Mon, Oct 25, 2010 at 8:54 PM, rgowka1 <rgowka1@REDACTED> wrote:

> Hi -
>
>
> My question is - Is there a way to generalize and extend the use of
> accumulators?
>
> 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}.
>
> thanks.


You could also make use of higher-order functions.  The key is that your
accumulator data structure is an arbitrary term and the accumulator function
can be an arbitrary (i.e. user defined) function.

-module(odds_and_evens).
-export([odds_and_evens/1, odds_and_evens_2/1]).

odds_and_evens(L) ->
    Counts = orddict:from_list([{evens,0}, {odds,0}]),
    lists:foldl(fun odds_and_evens_acc/2, Counts, L).

odds_and_evens_acc(Num, Acc) when Num rem 2 =:= 0 ->
    orddict:update_counter(evens, 1, Acc);
odds_and_evens_acc(_Num, Acc) ->
    orddict:update_counter(odds, 1, Acc).

odds_and_evens_2(L) ->
    Evens = length(lists:filter(fun is_even/1, L)),
    [{evens,Evens}, {odds, length(L) - Evens}].

is_even(N) ->
    N rem 2 =:= 0.


1> c(odds_and_evens).
{ok,odds_and_evens}
2> odds_and_evens:odds_and_evens([1,2,3]).
[{evens,1},{odds,2}]
3> odds_and_evens:odds_and_evens_2([1,2,3]).
[{evens,1},{odds,2}]
4> odds_and_evens:odds_and_evens(lists:seq(1,100)).
[{evens,50},{odds,50}]
5> odds_and_evens:odds_and_evens_2(lists:seq(1,100)).
[{evens,50},{odds,50}]
6> odds_and_evens:odds_and_evens(lists:seq(1,101)).
[{evens,50},{odds,51}]
7> odds_and_evens:odds_and_evens_2(lists:seq(1,101)).
[{evens,50},{odds,51}]
8> odds_and_evens:odds_and_evens(lists:duplicate(45,1)).
[{evens,0},{odds,45}]
9> odds_and_evens:odds_and_evens_2(lists:duplicate(45,1)).
[{evens,0},{odds,45}]


I feel like, in general, Erlang style tends towards explicit recursion
rather than HOFs but I don't understand why.  Maybe because function
composition and nesting is not as syntactically clean as it is in other
languages?  I'm specifically thinking of Haskell and Clojure which I got to
know before Erlang.

-Ryan


More information about the erlang-questions mailing list