List 如何在Erlang中使用闭包?
我有两个列表:L和E。我尝试编写一个函数,它返回另一个列表,其中包含E中元素的L出现次数List 如何在Erlang中使用闭包?,list,functional-programming,erlang,closures,anonymous-function,List,Functional Programming,Erlang,Closures,Anonymous Function,我有两个列表:L和E。我尝试编写一个函数,它返回另一个列表,其中包含E中元素的L出现次数 -module(mymodule). -export([count/2]). -export([numberOfOccurences/2]). count([Head|Tail], Counter) -> fun(Element) -> if [Head|Tail] == [] -> Counter; Element == Head -> count(Tail,
-module(mymodule).
-export([count/2]).
-export([numberOfOccurences/2]).
count([Head|Tail], Counter) ->
fun(Element) -> if
[Head|Tail] == [] -> Counter;
Element == Head -> count(Tail, Counter + 1);
Element /= Head -> count(Tail, Counter)
end
end.
numberOfOccurences(L, E) ->
lists:map(count(L, 0), E).
mymodule:numberofoccurrencess[1,2,“abc”,2,1,“abc”,4,1,1],[1,2,3,“abc”])
应返回[4,2,0,2]
。但它返回一个包含4个函数的列表。我做错了什么?这里发生的事情是,如果我们展开这个映射,count(L,0)
首先被调用,然后产生的乐趣被传递到列表:map
。当结果fun与E
的每个成员映射并传递给匿名函数时,大多数元素的返回值是调用count(Tail,Counter)
的结果,该函数返回一个函数
这里有一个函数的重写版本,可以正常工作。重要的是
count()
时,您可能会遇到匹配错误,更重要的是count()
的返回值,因此我将count()
调用的结果存储到F
中,然后使用传递的元素调用该函数-module(mymodule).
-export([count/2]).
-export([numberOfOccurences/2]).
count([],Counter) ->
fun(_) -> Counter end;
count([Head|Tail], Counter) ->
fun(Element) ->
if
Element == Head ->
F = count(Tail, Counter + 1),
F(Element);
Element /= Head ->
F = count(Tail, Counter),
F(Element)
end
end.
numberOfOccurences(L, E) ->
lists:map(count(L, 0), E).
结果:
> mymodule:numberOfOccurences([1,2,"abc",2,1,"abc",4,1,1], [1,2,3,"abc"]).
[4,2,0,2]
让我们看看你的函数count/2
count([Head|Tail], Counter) ->
fun(Element) -> if
[Head|Tail] == [] -> Counter;
Element == Head -> count(Tail, Counter + 1);
Element /= Head -> count(Tail, Counter)
end
end.
此函数包含作为函数定义的语句。这是最后一条语句,它将成为返回值。因此,呼吁:
lists:map(count(L, 0), E).
确实返回函数列表。
看看count函数的定义,它确实会对count进行递归调用,如果调用过它,它实际上可能会工作,但事实并非如此
我们可以在程序末尾添加一条语句,通过以下方式更改调用来调用的所有元素:
numberOfOccurences(L, E) ->
[F(E) || F <- lists:map(count(L, 0), E)].
然而,这些不运行
mymodule:numberOfOccurences([1,2,“abc”,2,1,“abc”,4,1,1],
[1,2,3,“abc”])。
**异常错误:错误的函数4
在函数mymodule中:'-numberofoccurrences/2-lc$^0/1-0-'/2(/home/tony/Projects/temp/src/mymodule.erl,第20行)
3>
作为一种风格,如果通过计数参数而不是以这种方式使用闭包,那么代码将更容易推理。有时闭包是必要的,例如在使用spawn/1时,但这不是其中之一
分析这个问题,我同意第一阶段是一张地图,但是我建议最好通过折叠来计算匹配元素。然而,我通常会用列表理解代替映射调用。我只是觉得它看起来更整洁
因此,我的解决方案如下:
-module occurances.
-export [count/2].
count(Data,KeyList) ->
[ lists:foldl(
fun(X,Count) when X =:= Key -> Count+1;
(_,Count) -> Count
end,
0,Data)
|| Key <- KeyList].
-模块事件。
-导出[计数/2]。
计数(数据、密钥列表)->
[列表:foldl(
当X=:=键->计数+1时的乐趣(X,计数);
(u,Count)->Count
完,,
0,数据)
||钥匙
乐趣()->
io:格式(“~p~n”,[count(数据,键列表)])
结束。
8> F=发生:关闭([1,2,“abc”,2,1,“abc”,4,1,1],[1,2,3,“abc”])。
F=发生:关闭([1,2,“abc”,2,1,“abc”,4,1,1],[1,2,3,“abc”])。
#乐趣
9> 产卵(F)。
产卵(F)。
[4,2,0,2]
10>
-module occurances.
-export [count/2].
count(Data,KeyList) ->
[ lists:foldl(
fun(X,Count) when X =:= Key -> Count+1;
(_,Count) -> Count
end,
0,Data)
|| Key <- KeyList].
make_closure(Data,KeyList) ->
fun() ->
io:format("~p~n",[count(Data,KeyList)])
end.
8> F=occurances:make_closure([1,2,"abc",2,1,"abc",4,1,1], [1,2,3,"abc"]).
F=occurances:make_closure([1,2,"abc",2,1,"abc",4,1,1], [1,2,3,"abc"]).
#Fun<occurances.0.132489632>
9> spawn(F).
spawn(F).
[4,2,0,2]
<0.107.0>
10>