Stream Erlang执行流操作的方式是什么?

Stream Erlang执行流操作的方式是什么?,stream,erlang,Stream,Erlang,假设我想做如下事情: dict .values() .map(fun scrub/1) .flatMap(fun split/1) .groupBy(fun keyFun/1, fun count/1) .to_dict() 在Erlang中实现这一点最优雅的方法是什么?没有直接简单的方法。我看到的所有尝试都比简单的构图更糟糕。如果您查看Erlang中的大多数开源项目,您会发现它们使用泛型组合。重新使用您的示例: to_dict( groupBy(fun keyFun/1,

假设我想做如下事情:

dict
  .values()
  .map(fun scrub/1)
  .flatMap(fun split/1)
  .groupBy(fun keyFun/1, fun count/1)
  .to_dict()

在Erlang中实现这一点最优雅的方法是什么?

没有直接简单的方法。我看到的所有尝试都比简单的构图更糟糕。如果您查看Erlang中的大多数开源项目,您会发现它们使用泛型组合。重新使用您的示例:

to_dict(
groupBy(fun keyFun/1, fun count/1, 
flatMap(fun split/1, 
map(fun scrub/1, 
values(dict))))).

在Erlang中,这不是一个自然的构造。如果你有两个函数,我会使用正则合成:

lists:flatten(lists:map(fun (A) ->
                            do_stuff(A)
                        end,
                        generate_list())).
对于较长的操作系列,中间变量:

Dict = #{hello => world, ...},
Values = maps:values(Dict),
ScrubbedValues = lists:map(fun scrub/1, Values),
SplitValues = lists:flatten(lists:map(fun split/1, ScrubbedValues)),
GroupedValues = basil_lists:group_by(fun keyFun/1, fun count/1, SplitValues),
Dict2 = maps:from_list(GroupedValues).
如果你想将所有这些操作集中在一个镜头中,情况就是这样

然而,我更可能用另一种方式来写:

-spec remap_values(map()) -> map().
remap_values(Map) ->
    map_values(maps:values(Map)).

-spec map_values(list()) -> map().
map_values(Values) ->
    map_values(Values, [], []).

-spec map_values(list(), list(), list()) -> map().
map_values([], OutList, OutGroup) ->
    %% Base case: transform into a map
    Grouped = lists:zip(OutGroup, OutList),
    lists:foldl(fun ({Group, Element}, Acc = #{Group := Existing}) ->
                        Acc#{Group => [Element | Existing]};
                    ({Group, Element}, Acc) ->
                        Acc#{Group => [Element]}
                end,
                #{},
                Grouped;
map_values([First|Rest], OutList, OutGroup) ->
    %% Recursive case: categorize process the first element and categorize the result
    Processed = split(scrub(First)),
    Categories = lists:map(fun categorize/1, Processed),
    map_values(Rest, OutList ++ Processed, OutGroup ++ Categories).

实际的正确实现在很大程度上取决于代码的运行方式——我在这里编写的代码非常简单,但可能无法在大量数据上运行良好。如果您确实希望处理源源不断的数据,您需要自己编写(尽管您可能会发现Gen Server是一个非常有用的框架)。

谢谢。这是一个遗憾:(奇怪的是,这是一个我在实际代码中很少需要的构造。我可能会在dict上做一个映射操作。