5

L と E の 2 つのリストがあります。E の要素に対して L からの出現回数を含む別のリストを返す関数を作成しようとしました。

-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:numberOfOccurences[1,2,"abc",2,1,"abc",4,1,1], [1,2,3,"abc"])返品する必要があります[4,2,0,2]。ただし、4 つの関数を含むリストが返されます。私は何を間違っていますか?

4

3 に答える 3

10

ここで何が起こっているかというと、このマップを展開すると、count(L, 0)が最初に呼び出され、次にその結果の fun が に渡されlists:mapます。その結果の fun が の各メンバーにマップされE、無名関数に渡されると、ほとんどの要素の戻り値はcount(Tail,Counter)、関数を返す を呼び出した結果になります。

これは、機能する関数の書き直されたバージョンです。大きなことは

  1. 基本ケースを修正しました。そうしないと、空のセットが に渡されたときに一致エラーが発生する可能性が高くなりcount()、さらに重要なことに、
  2. クロージャーでは、適切な再帰を確実にするために、 の戻り値を呼び出す必要があるため、呼び出し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]
于 2013-01-17T04:30:47.910 に答える