8

我需要从 foldl 中解脱出来。这是一个虚拟示例,当我计算列表中值的总和并遇到太大的值(即 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.

我知道这个例子是人为的,但是有什么好的方法可以打破折叠(我知道折叠总是扫描整个结构)?

请注意,即使我从折叠中中断,我也需要检索正确的数据。在这种情况下,我应该从以前的迭代中获取数据(就像在我的示例中所做的那样)。

4

2 回答 2

8

只是好奇,在foldl这里使用有什么意义?如果需要突围,使用递归,foldl不是为它设计的。

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.

更新:

另一种选择是使用takewhile

lists:foldl(fun(E, A) -> A + E end, 0, lists:takewhile(fun(E) -> E < 10 end, L))
于 2011-12-07T21:45:47.247 回答
7

你做对了,使用带有 try/catch 的 throw 进行非本地返回。如果函数从 fun 中查看返回值来决定是否继续,它就不再是 foldl 了。

于 2011-12-07T13:21:21.177 回答