4

我有兩個列表:L和E我嘗試寫一個函數,它具有從低出現次數爲元素的個數返回另一個列表E.如何在Erlang中使用閉包?

-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個函數的列表。我究竟做錯了什麼?

回答

8

這裏發生了什麼,如果我們展開此地圖,count(L, 0)被首先調用,那麼最終的樂趣將傳遞到lists:map。當結果樂趣與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]