[erlang-questions] Nested for-loops, there has to be a better way to do this

Cláudio Amaral <>
Wed Jul 29 18:25:26 CEST 2009


Used some of previous code...

I tried to make a polymorphic function and coupled an example... this 
ended a little bit confusing, but as you can see, it makes all 
iterations (check the printed indexes, reversed).

The body behaviour is the tricky stuff to code, but in exchange it is 
modular...

Since I am an erlang newb, please correct anything you see as bad 
programming

Cláudio

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(for_loop).

-export([for/4, show/0]).


for(BodyFunc, BodyArgs, StepFunc, {First, Last}) ->
    for_(BodyFunc, BodyArgs, StepFunc, {First, Last}, First).


for_(BodyFunc, BodyArgs, StepFunc, {_, LastTerm}, LastTerm) ->
    BodyFunc(BodyArgs, LastTerm);
for_(BodyFunc, BodyArgs, StepFunc, LimitsTuple, IndexTerm) ->
    NextArgs = BodyFunc(BodyArgs, IndexTerm),
    for_(BodyFunc, NextArgs, StepFunc, LimitsTuple, StepFunc(IndexTerm)).


show() ->
    for( fun(A1,A2)->body1(A1,A2) end,
     [{0,3}, [{1,0}], [{3,6},{1,2}]],
     fun(I) -> I+1 end,
     {0,3}
    ).


body1([ LimitsTuple, [{NLoop,II}|Rest], []],I) ->
    print([ I | lists:map(fun({_,Snd}) -> Snd end, Rest) ]),
    IndexInfo = [{NLoop,II}|Rest],
    [ LimitsTuple, IndexInfo, []];
body1([ LimitsTuple, [{NLoop,II}|Rest], [{X1,Xn}|XS]],I) ->
    for( fun (A1,A2)->body1(A1,A2) end,
     [ LimitsTuple, [ {NLoop+1,II}, {NLoop,I} | Rest ], XS],
     fun(K) -> K+1 end,
     {X1,Xn}
    ),
    IndexInfo = [{NLoop,II}|Rest],
    [ LimitsTuple, IndexInfo, [{X1,Xn}|XS] ].

print(Numbers) ->
    io:format("indexes ~p~n", [Numbers]).


 escreveu:
> Regards,
> Z.
>
>   
>> I was playing around with the idea of implementing a nested for-loop
>> like construct (I will concede, they are evil, but at rare times,
>> necessary.)  In non-functional programming languages, they are trivial
>> to do.  However, this has proved to be one of those simple things that
>> are a pain in the neck for me.  The idea was to be able to pass in a
>> list [5, 5, 10] (for example) and go through it all like 3 dimensional
>> array.  The below illustration is far from elegant (it's almost 23:00
>> where I live and need to go to work tomorrow early, so no time to come
>> up with something more sane :) ), but is there as an inquisitive
>> exercise.  Now, in my opinion, this implementation sucks (first time
>> I've ever gave such a problem a shot in Erlang.)
>>
>> Is there a better way to do this?  Anyone would like to demonstrate
>> it?
>>
>> Note: I've tested this code with the lists [2, 4] and [2, 4, 5].
>>
>> Compiled with:
>> Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 5.6.5
>>
>> My code:
>> ======================================
>> -module(loopWrapper).
>>
>> -export([runLoop/1]).
>>
>> runLoop(List) ->
>>   [FirstVal | RestList] = List,
>>   NextVal = FirstVal - 1,
>>   if (length(RestList) > 0) and (FirstVal > 0) ->
>>     io:format("~B~n~n", [FirstVal]),
>>     runLoop(RestList),
>>     io:format("~n~n"),
>>     runLoop([NextVal | RestList]);
>>   FirstVal > 0 ->
>>     io:format("~B", [FirstVal]),
>>     runLoop([NextVal]);
>>   true ->
>>     null
>>   end.
>>
>> ________________________________________________________________
>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>> erlang-questions (at) erlang.org
>>
>>
>>     
>
>
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>   



More information about the erlang-questions mailing list