这个Erlang代码是惯用的吗?

时间:2015-11-27 15:55:04

标签: haskell erlang idiomatic

我正在对Erlang,Haskell,Elixir和ES6进行比较,而且我对Erlang和Elixir的熟悉程度较低,但我想公平地表示所有这些语言,所以这是一个很好的Erlang代码?

-module(mapreduce).
-export([map_reduce/1]).

add_to_key(KV, Sum) -> {Key, Value} = KV,
                       Tmp = proplists:get_value(Key, Sum, 0),
                       Newlist = proplists:delete(Key, Sum),
                       lists:append([{Key, Value + Tmp}], Newlist).

map_reduce(Pl) -> lists:foldl(fun add_to_key/2, [], Pl).

- 谢谢你们!

顺便说一句,如果你们想看,那么Haskell版本就是这样的:

module MapReduce where
import qualified Data.Map as M

mapReduce :: [(String, Int)] -> [(String, Int)]
mapReduce = foldl addToKey []
    where addToKey hl (k, v) = M.toList . M.insertWith (+) k v $ M.fromList hl

2 个答案:

答案 0 :(得分:1)

我会这样写(在shell中测试版本> = 17),以限制列表创建/复制的数量:

android:theme="@style/AppTheme"

答案 1 :(得分:0)

更多惯用的Erlang将在函数子句头add_to_key({Key, Value}, Sum)中使用模式匹配,但是当您在Haskell中使用Data.Map时,您也应该在Erlang中使用类似的键/值存储。在R17之前的版本中,它主要是dict,但现在我们也有地图。将add_to_key/2作为额外功能也是不常见的(就个人而言,我更喜欢它,但它不是惯用的。):

map_reduce(L) ->
    F = fun({K, V}, M) ->
            maps:put(K, V + maps:get(K, M, 0), M)
        end,
    maps:to_list(lists:foldl(F, #{}, L)).

无论如何,使用排序列表的方法并不罕见,如Pascal' answer

map_reduce(L) ->
    F = fun({K, V1}, [{K, V2}|Acc]) ->
            [{K, V1 + V2}|Acc];
           ({K, V}, Acc) ->
            [{K, V}|Acc]
        end,
    lists:foldl(F, [], lists:sort(L)).