2016-07-22 3 views
1

Mein Haskell Code werfen ist wie folgtFunktion Elem Fehler

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

Wenn kompiliert es zeigt diese Fehler

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)] 

Mein Verständnis ist, dass Elem zwei Argumente akzeptiert, verstehe ich nicht, wie ich bin Übergeben von 4 Argumenten in dem obigen Code als die Map-Funktion sollte nur eine Liste zurückgeben.

Antwort

8

Sie sind übergeben vier Argumente an die elem Funktion. Funktionsanwendung zuordnet immer links, so dass der Ausdruck

f a b c d 

wird wie folgt analysiert:

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

Daher Ihr Beispiel wird wie folgt analysiert zu werden:

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

Das heißt, elem ist "auf vier Argumente angewendet", aber natürlich sind alle Haskell-Funktionen eigentlich nur Funktionen eines Arguments, nur Curry. Was Sie eigentlich wollen, ist eine andere Gruppierung, so brauchen Sie nur einige Klammern hinzuzufügen:

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

Alternativ könnten Sie use $ to avoid writing the parentheses:

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

Oder Sie könnten elem Infix schreiben, die a allgemeines Idiom in Haskell. Wie $, wird dies auch die Priorität ändern, um was Sie wollen:

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

Großartige Erklärung! Vielen Dank. Das funktioniert. – rt88

2

Die vier Argumente, die Sie übergeben, sind 0, map, mod x und [3.. (x-1)]. Sie wollten mod x und [3.. (x-1)] als Argumente an map übergeben und dann das Ergebnis als zweites Argument an elem übergeben, aber Haskell kann das ohne Klammern oder $ nicht wissen. So machen Sie Ihren Code arbeiten sie hinzufügen:

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

Oder können Sie Infixschreibweise verwenden, wobei in diesem Fall Vorrangregeln (Präfix Funktionsanwendung bindet fester als jedes Infixoperator) beseitigt die Notwendigkeit für Klammern:

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

Natürlich! Das funktioniert. Danke: D – rt88