2016-07-22 109 views
1

我的Haskell代碼如下所示功能ELEM拋出錯誤

isNotPrime x = elem 0 map (mod x)[3.. (x-1)]  

在編譯時就說明這些錯誤

Couldn't match expected type ‘(t1 -> t1) -> [t1] -> t’ 
       with actual type ‘Bool’ 
    The function ‘elem’ is applied to four arguments, 
    but its type ‘([a0] -> [b0]) 
       -> ((a0 -> b0) -> [a0] -> [b0]) -> Bool’ 
    has only two 
    In the expression: elem 0 map (mod x) [3 .. (x - 1)] 
    In an equation for ‘prime’: 
     prime x = elem 0 map (mod x) [3 .. (x - 1)] 

我的理解是,ELEM接受兩個參數,我不明白我怎麼在上面的代碼中傳遞4個參數,因爲map函數應該只返回一個列表。

回答

8

將四個參數傳遞給elem函數。功能應用總是關聯左邊,這樣的表達

f a b c d 

被解析如下:

((((f a) b) c) d) 

因此,你的例子是越來越解析如下:

((((elem 0) map) (mod x)) [3.. (x-1)]) 

也就是說,elem是被「應用於四個參數」,但當然所有的Haskell函數實際上只是一個參數的函數,只是curried。你實際上想要的是一個不同的分組,所以你只需要添加一些括號:

elem 0 (map (mod x) [3.. (x-1)]) 

或者,你可以use $ to avoid writing the parentheses

elem 0 $ map (mod x) [3.. (x-1)] 

或者你可以寫elem綴,這是一個Haskell中常見的成語。像$,這也會改變優先級爲你想要的:

0 `elem` map (mod x) [3.. (x-1)] 
+0

很好的解釋!謝謝。這工作。 – rt88

2

您傳遞的四個參數是0,map,mod x[3.. (x-1)]。您打算將mod x[3.. (x-1)]作爲參數傳遞給map,然後將結果作爲第二個參數傳遞給elem,但Haskell無法知道沒有括號或$。因此,爲了使你的代碼工作將它們添加:

isNotPrime x = elem 0 (map (mod x) [3.. (x-1)]) 
-- or 
isNotPrime x = elem 0 $ map (mod x) [3.. (x-1)] 

或者你可以使用中綴表示法,在這種情況下,優先規則(前綴功能應用的優先級比任何管道符更緊)消除了括號的需要:

isNotPrime x = 0 `elem` map (mod x) [3.. (x-1)] 
+0

當然!這工作。謝謝:D – rt88