将函数同时应用于 Erlang 中元组中的每个元素

Concurrently apply function to each element in a tuple in Erlang

我有一个元组{apple, pear, orange, banana}

我还有一个功能make_juice/1:

 make_juice(apple) ->
    apple_juice();
 make_juice(pear) ->
    pear_juice();
 make_juice(orange) ->
    orange_juice();
 make_juice(banana) ->
    banana_juice().

我想把这个函数应用到元组中的每个元素,所以我得到了结果

{apple_juice, pear_juice, orange_juice, banana_juice}

因为所有函数apple_juice/0pear_juice/0orange_juice/0banana_juice/0 都可能意外失败。我想申请我不希望它打断我的结果。

我想同时将函数应用于元素。在任何失败的情况下,我仍然会得到部分结果:

{apple_juice, fail, orange_juice, fail}

最简单的方法是什么?

你可以试试这段代码,它并行执行映射,同时如果有异常则将结果替换为失败

-module(juice).
-compile(export_all).

make_juice(apple) ->
    apple_juice;
make_juice(pear) ->
    pear_juice;
make_juice(orange) ->
    orange_juice;
make_juice(banana) ->
    0/0.

pmap(Function, List) ->    
    S = self(),
    Pids = lists:map(fun(El) ->
                 spawn(fun() ->
                       execute(S, Function, El) end) 
             end, 
             List),
    gather(Pids).

execute(Recv, Function, Element) ->
    Recv ! {self(), Function(Element)}.

gather([]) ->
    [];
gather([H|T]) ->
    receive
    {H, Ret} ->
        [Ret|gather(T)]
    end.



test() ->
    Elements = [apple, banana, pear, orange],
    pmap(fun(X) -> 
         try make_juice(X) of
             Result -> Result
         catch
             _:_ ->
             fail
         end
     end, Elements).

和测试:

rorra-air:~/erlang > erl
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Eshell V6.4  (abort with ^G)
1> c(juice).
juice.erl:11: Warning: this expression will fail with a 'badarith' exception
{ok,juice}
2> juice:test().
[apple_juice,fail,pear_juice,orange_juice]
3>