2015-11-30 71 views
0

我試圖編寫一個並行排序的Qsort函數,並將此代碼直接轉換爲Elixir,但由於某種原因,當我運行pqsort:pqsort([5, 4, 3, 10, 1]).時,它失敗並出現此錯誤:Erlang的錯誤參數錯誤spawn_link/3

** exception error: bad argument 
    in function spawn_link/3 
     called as spawn_link(pqsort,#Fun<pqsort.0.102886275>,[<0.33.0>,[3,2,1]]) 
    in call from pqsort:pqsort_worker/2 (pqsort.erl, line 6) 

這裏是我的代碼:

-module(pqsort). 
-export([pqsort/1, pqsort_worker/2]). 

pqsort_worker(Listener, []) -> Listener ! {self(), []}; 
pqsort_worker(Listener, [H | T]) -> 
    PID_1 = spawn_link(pqsort, fun pqsort_worker/2, [self(), [ X || X <- T, H >= X ]]), 
    PID_2 = spawn_link(pqsort, fun pqsort_worker/2, [self(), [ Y || Y <- T, H < Y ]]), 
    receive 
     {PID_1, List_1} -> 
      receive 
       {PID_2, List_2} -> Listener ! {self(), List_1 ++ [H] ++ List_2} 
      end; 
     {PID_2, List_2} -> 
      receive 
       {PID_1, List_1} -> Listener ! {self(), List_1 ++ [H] ++ List_2} 
      end 
    end. 

pqsort(List) -> element(2, pqsort_worker(self(), List)). 
+0

你一定要明白,這是相比於快速排序大規模pessimization? – zxq9

+0

是的......這只是我試驗Erlang並行性。我並不打算這麼快。我只是大部分時間都在搞亂。 –

+0

標題更改使問題完全不同。檢查spawn_link/3的typespec:http://www.erlang.org/doc/man/erlang.html#spawn_link-3第二個參數是一個原子,而不是一個樂趣。 Funs已經構建並且已經構建 - Erlang允許您使用函數的標籤+ args列表(其長度決定了arity)在任何需要'{Mod,Fun,Args}'類型值的任何位置調用函數。 – zxq9

回答

1

如果你去documentation,你會發現,第二個參數是不是一個功能,但原子

只要改變

PID_1 = spawn_link(pqsort, fun pqsort_worker/2, [self(), [ X || X <- T, H >= X ]]), 
PID_2 = spawn_link(pqsort, fun pqsort_worker/2, [self(), [ Y || Y <- T, H < Y ]]), 

PID_1 = spawn_link(pqsort, pqsort_worker, [self(), [ X || X <- T, H >= X ]]),    |([email protected])1> c("/Users/rorra/erlang/pqsort", [{outdir, "/Users/rorra/erlang/"}\ 
PID_2 = spawn_link(pqsort, pqsort_worker, [self(), [ Y || Y <- T, H < Y ]]), 
+0

哦!謝謝!你能解釋一下這個區別嗎?我認爲所有的頭等功能都必須用'fun'關鍵字來限定。 –

+0

@ChristopherDumas當你去看文檔時:http://www.erlang.org/doc/man/erlang.html#spawn-3 你會注意到第二個參數不是一個函數,而是一個原子。 如果我的回答解決了這個問題,請隨時接受它作爲問題的正確答案,謝謝:) – rorra

+0

我真的很喜歡你的答案。也許你能否將你的解釋加入未來人的實際答案中? –