Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easy way to break foldl

Tags:

erlang

fold

I need to break from foldl. Here is a dummy example how to break from fold when I count sum of values in a list and meet too big value (i.e. 10)

   L = [1,2,3,4,10,5,6,7],

   Res = 
      try
         lists:foldl(
            fun(I, Value) ->
               if (I < 10) ->
                  Value + I;
               true ->
                  throw({too_big_value, Value})
               end
            end,
            0, L)
      catch
         throw:{too_big_value, Value} -> Value
      end,

   Res.

I know this example is artificial but are there any nice method to break out fold (I know that fold always scan the whole structure)?

Please note, that i need to retrieve correct data even if i break from fold. In this case i should get data from previous iteration (as it done in my example).

like image 289
ravnur Avatar asked Dec 07 '11 08:12

ravnur


2 Answers

Just curious, what is the point of using foldl here? If you need to break out, use recursion, foldl is not designed for it.

main([]) ->
  L = [1,2,3,4,5,10,6,7],

   io:format("[~w]", [s(L, 0)]).

s([], S) ->
  S;

s([H|T], S) ->
  if (H < 10) ->
    s(T, S + H);
  true ->
    S
  end.

Update:

Another options is to use takewhile:

lists:foldl(fun(E, A) -> A + E end, 0, lists:takewhile(fun(E) -> E < 10 end, L))
like image 144
Victor Moroz Avatar answered Sep 20 '22 20:09

Victor Moroz


You're doing it right, using a throw with try/catch for nonlocal return. If the function looked at the return value from the fun to decide whether or not to continue, it wouldn't be foldl anymore.

like image 23
RichardC Avatar answered Sep 21 '22 20:09

RichardC