2016-04-14 12 views
0

Hey, also ich lernte Haskell in der Klasse und mir wurde das Problem gegeben, alle Instanzen von etwas aus einer Liste zu entfernen. Das ist mein Ziel, aber ich stoße auf diesen Fehler, dem ich nicht folgen kann.Haskell: Konnte den erwarteten Typ nicht mit dem tatsächlichen Typ übereinstimmen

--delete element from list 
removeElement :: [a] -> [a] 
removeElement x [] = [] 
removeElement x aList = 
    if (head aList) == x 
     then removeElement x (tail aList) 
     else aList 

Der Fehler, den ich erhalten, ist dies:

Couldn't match expected type `[[a]] -> [[a]]' 
       with actual type `[a]' 
    Relevant bindings include 
     removeElement :: [a] -> [a] (bound at hwmk3.hs:8:1) 
    The equation(s) for `removeElement' have two arguments, 
    but its type `[a] -> [a]' has only one 

Ich vermute, dass die Syntax falsch ist, aber ich bin nicht sicher, wie es zu beheben. Danke für Ihre Hilfe.

+1

Die Signatur sagt, dass Ihre Funktion ein Argument hat, und die Gleichung sagt, es hat zwei. Wohlgemerkt, das * kann * in Haskell Sinn haben, nur wahrscheinlich nicht, was du hier brauchst. –

Antwort

5

Ein paar Dinge:

Ihre Typanmerkung zeigt an, dass Ihre Funktion einen einzige Liste Parameter erhalten und eine Liste zurück, während die Implementierung zeigt an, dass Sie zwei Parameter erhalten sollen, von denen die ersten ein einzelnen Element ist.

Da Sie == verwenden, um zu vergleichen, müssen Sie sicherstellen, dass Ihr Typ der Eq typeclass ist.

Ihre Typenannotation sollte wohl so aussehen:

removeElement :: Eq a => a -> [a] -> [a] 

Sie auch Dinge, durch die Nutzung von Musteranpassung unter vereinfachen kann. Sie brauchen nicht head und tail zu verwenden, wenn Sie Ihre Funktion wie folgt definieren:

removeElement x [email protected](y:ys) = 
    if y == x 
    then removeElement x ys 
    else aList 

jedoch gibt es ein logischer Fehler in Ihrer bedingte Anweisung. Da dies wie Hausaufgaben klingt, überlasse ich es Ihnen, die Antwort zu finden. Tipp, versuchen removeElement 3 [1, 2, 3]

+0

Ah, das ist mehr von der Funktion, für die ich vorging. Ich war mir der Syntax nicht bewusst. Vielen Dank! Das hat sehr geholfen. –

0

Ihre Art Signatur sollte

removeElement :: a -> [a] -> [a] 

auch sein, es sieht aus wie Ihre Funktion nicht tut, was Sie denken, es zu tun.

1

Wenn Sie die explizite Typdeklaration Ihrer Funktion weggelassen hätten, hätte Haskell etwas wie a -> [a] -> [a] gefolgert. In der Tat, es immer noch schließt das, weshalb es sich beschwert, dass es nicht mit Ihrem angegebenen Typ übereinstimmt.

Das von Haskell berichtete Problem ist das. Ein Blick auf Ihre zweite Gleichung, die desugars zu

removeElement x = \aList -> if (head aList) == x then removeElement x (tail aList) else aList 

ein paar Dinge sind "offensichtlich":

  1. x :: [a] als Argument für removeElement.
  2. Der Lambda-Ausdruck hat Typ t -> v für einige Typen t und v.

Aber wir haben bereits gesagt, dass removeElement :: [a] -> [a], so können wir mit Werten kommen für t und v so dass [a] ~ t -> v? Könnte sein. Lassen Sie uns Schlussfolgertypen halten.

t ist die Art von aList, die wir von head aList == x ableiten kann [[a]] zu sein. Überspringt den rekursiven Aufruf für jetzt, können wir auch sehen, dass aList der Rückgabewert ist, also v ist auch [[a]]. Somit ist t -> v wirklich [[a]] -> [[a]].

Können wir einen Wert vom Typ [[a]] -> [[a]] mit [a] abgleichen?

Nein, weshalb Sie die genaue Fehlermeldung erhalten, die Sie tun.

Verwandte Themen