在Erlang中迭代笛卡尔积,而不首先生成列表

在Erlang中迭代笛卡尔积,而不首先生成列表,erlang,Erlang,Erlang与以下Python代码的等价物是什么: for x in range(9): for y in range(9): for z in range(9): foo(x, y, z) 我知道我可以先用C=[{X,Y,Z}| X生成乘积,你可以用三个递归函数来实现 您可能可以在函数头中使用一些复杂的模式匹配来实现这一点 但跳过辅助列表创建的最简单方法是在列表中调用函数 C = [foo(X, Y, Z) || X<- lists:se

Erlang与以下Python代码的等价物是什么:

for x in range(9):
    for y in range(9):
        for z in range(9):
            foo(x, y, z)

我知道我可以先用
C=[{X,Y,Z}| X生成乘积,你可以用三个递归函数来实现

您可能可以在函数头中使用一些复杂的模式匹配来实现这一点

但跳过辅助列表创建的最简单方法是在列表中调用函数

C = [foo(X, Y, Z) || X<- lists:seq(1,9), 
                     Y<- lists:seq(1,9),  
                     Z<- lists:seq(1,9)]

C=[foo(X,Y,Z)| | X列表理解仍然迫使您在内存中创建辅助列表。
在处理庞大的数据集时,你应该避免使用它。每次编写递归函数也很尴尬,因此我提出了自己的泛型for函数。它在遍历时比直接递归或列表理解稍微慢一点,但它的内存稳定、泛型且易于使用

用法:

(for({10}))(
    fun (X) -> io:format("~p ",[X]) end).
> 1 2 3 4 5 6 7 8 9 10

(for({10, -10, -2}))(
    fun (X) -> io:format("~p ",[X]) end).
> 10 8 6 4 2 0 -2 -4 -6 -8 -10
也适用于列表:

(for(lists:seq(10, -10, -2)))(
    fun (X) -> io:format("~p ",[X]) end).
> 10 8 6 4 2 0 -2 -4 -6 -8 -10
也可以将步骤或保护定义为一个函数:

(for({256, 1.1, fun (X) -> math:sqrt(X) end, fun (X, Range) -> X > Range end}))(
    fun (X) -> io:format("~p ",[X]) end).
> 256 16.0 4.0 2.0 1.4142135623730951 1.189207115002721
如果将双参数函数的初始累加器传递给,则可以使用累加器功能,就像列表:foldl/3一样。还需要将初始累加器传递给:

Fact = (for(1, {1, 5}))(
    fun(X, Acc) ->
      X * Acc
    end),
io:format("~p", [Fact]).
> 120

e_fact(N) ->
  {_, E} = (for({1, 1}, {1, N}))( % i assumed  1/0! equals 1
    fun(X, {LastFact, Sum}) ->
      Fact = LastFact * X,
      {Fact, Sum + 1 / Fact}
    end),
  E.
io:format("e=~p", [e_fact(10)]).
> e=2.7182818011463845
步进和保护功能也可以依赖于累加器。只需再传递一个参数即可

嵌套循环查找勾股三元组。使用闭包很容易:

pyth_lists(N) ->
  [io:format("~p ", [{A, B, C}]) ||
    A <- lists:seq(1, N),
    B <- lists:seq(A + 1, N),
    C <- lists:seq(B + 1, N),
    A * A + B * B == C * C].

pyth_for(N) ->
  (for({1, N}))(
    fun(A) ->
      (for({A + 1, N}))(
        fun(B) ->
          (for({B + 1, N}))(
            fun(C) ->
              case A * A + B * B == C * C of
                true -> io:format("~p ", [{A, B, C}]);
                false -> ok
              end
            end)
        end)
    end).
pyth_列表(N)->
[io:格式(“~p”,[{A,B,C}])||
A.
(对于({B+1,N}))(
乐趣(C)->
案例A*A+B*B==C*C
true->io:format(“~p”,[{A,B,C}]);
false->ok
结束
(完)
(完)
(完)。
它对于外部存储库来说太小了。我将它保存在我的实用程序模块中。 如果您觉得有帮助,以下是代码:

-export([for/1, for/2]).

for(Through) ->
  for([], Through).

for(InitAcc, Opts) when is_tuple(Opts) ->
  {Init, Range, Step, Guard} = for_apply_default_opts(Opts),
  fun(Fun) -> 
    UpdFun = if
      is_function(Fun, 1) ->
        fun(I, _FAcc) -> Fun(I) end;
      is_function(Fun, 2) ->
        Fun
    end,
    for_iter(UpdFun, InitAcc, Init, Range, Step, Guard) end;

for(InitAcc, List) when is_list(List) ->
  fun(Fun) -> for_list_eval(Fun, InitAcc, List) end.

for_iter(Fun, Acc, I, Range, Step, Guard) ->
  case Guard(I, Range, Acc) of
    false ->
      Acc;
    true ->
      NewAcc = Fun(I, Acc),
      for_iter(Fun, NewAcc, Step(I, NewAcc), Range, Step, Guard)
  end.

for_list_eval(Fun, Acc, List) ->
  if
    is_function(Fun, 1) ->
      lists:foreach(Fun, List);
    is_function(Fun, 2) ->
      lists:foldl(Fun, Acc, List)
  end.

for_apply_default_opts({Range}) ->
  DefaultInit = 1,
  for_apply_default_opts({DefaultInit, Range});

for_apply_default_opts({Init, Range}) ->
  DefaultStep = 1,
  for_apply_default_opts({Init, Range, DefaultStep});

for_apply_default_opts({Init, Range, Step}) ->
  DefaultGuard = case (Step > 0) or is_function(Step) of
                   true -> fun(I, IterRange, _Acc) -> I =< IterRange end;
                   false -> fun(I, IterRange, _Acc) -> I >= IterRange end
                 end,
  for_apply_default_opts({Init, Range, Step, DefaultGuard});

for_apply_default_opts({Init, Range, Step, Guard}) when is_function(Guard, 2) ->
  for_apply_default_opts({Init, Range, Step, fun(I, IterRange, _Acc) -> Guard(I, IterRange) end});

for_apply_default_opts({Init, Range, Step, DefaultGuard}) when is_number(Step) ->
  for_apply_default_opts({Init, Range, fun(I, _Acc) -> I + Step end, DefaultGuard});

for_apply_default_opts({Init, Range, Step, DefaultGuard}) when is_function(Step, 1) ->
  for_apply_default_opts({Init, Range, fun(I, _Acc) -> Step(I) end, DefaultGuard});

for_apply_default_opts({_Init, _Range, _Step, _DefaultGuard} = Opts) ->
  Opts.
-导出([for/1,for/2])。
对于(通过)->
对于([],至)。
for(InitAcc,Opts)何时为元组(Opts)->
{Init,Range,Step,Guard}=for_apply_default_opts(opts),
乐趣(乐趣)->
UpdFun=if
是功能(乐趣,1)->
乐趣(I,FAcc)->乐趣(I)结束;
是功能(乐趣,2)->
乐趣
完,,
对于iter(UpdFun、InitAcc、Init、范围、步进、保护)结束;
对于(InitAcc,List)什么时候是列表(List)->
fun(fun)->for_list_eval(fun,InitAcc,list)结束。
对于iter(乐趣、Acc、I、范围、步骤、防护)->
外壳防护装置(I、范围、附件)
错误->
行政协调会;
正确->
NewAcc=乐趣(I,Acc),
对于iter(乐趣、新ACC、步骤(I、新ACC)、射程、步骤、防护)
结束。
对于列表评估(乐趣、Acc、列表)->
如果
是功能(乐趣,1)->
列表:foreach(乐趣,列表);
是功能(乐趣,2)->
列表:foldl(乐趣、Acc、列表)
结束。
对于_apply _default _opts({Range})->
DefaultInit=1,
for_apply_default_opts({DefaultInit,Range});
对于\u apply\u default\u opts({Init,Range})->
DefaultStep=1,
for_apply_default_opts({Init,Range,DefaultStep});
对于\u apply\u default\u opts({Init,Range,Step})->
DefaultGuard=案例(步骤>0)或是
真->有趣(I,IterRange,_Acc)->I=fun(I,IterRange,_Acc)->I>=IterRange结束
完,,
for_apply_default_opts({Init,Range,Step,DefaultGuard});
当函数(Guard,2)->
对于应用默认选项({Init,Range,Step,fun(I,iterange,_Acc)->Guard(I,iterange)end});
对于_apply _default _opts({Init,Range,Step,DefaultGuard}),当_number(Step)->
for_apply_default_opts({Init,Range,fun(I,_Acc)->I+Step end,DefaultGuard});
当函数(步骤1)->
for_apply_default_opts({Init,Range,fun(I,_Acc)->步骤(I)end,DefaultGuard});
对于应用默认选项({{u Init,{u Range,{u Step,{u DefaultGuard}=opts)->
选择。