2017-09-18 2 views
2

Ich versuche, eine Funktion zu schreiben, die feststellen wird, ob ein Element in einer Liste vorhanden ist, die beide vom Benutzer bereitgestellt werden. Ich denke, eine rekursive Lösung ist am besten. Das habe ich:Ermitteln, ob Wert ein Element einer Liste in Haskell ist

isElement :: a -> [b] -> Bool 
isElement a [] = False 
isElement a (x:xs) = if a == x then True 
        else isElement a xs 

Aber es kann nicht kompilieren. Der Fehler lautet "Der erwartete Typ -a konnte dem tatsächlichen Typ -b 'nicht entsprechen". Ich weiß nicht, was das bedeutet oder wie man das Problem beheben kann.

+2

Ihre Typ-Signatur ist falsch. '==' erfordert, dass seine Operanden den gleichen Typ haben, aber Sie haben 'a :: a' und' x :: b'. – melpomene

+0

Und nicht irgendein Typ; 'a' muss eine Instanz der Klasse' Eq' sein: 'isElement :: Eq a => a -> [a] -> Bool'. – chepner

+0

Sie sollten immer misstrauisch sein, wenn Sie in der Nähe von 'if' mit' True' oder 'False' arbeiten. Normalerweise bedeutet das, dass die Logik direkter ausgedrückt werden kann, ohne ein "if". In diesem Fall ist das wahr. Sie könnten den Körper der zweiten Gleichung als '(a == x) || schreiben isElement a xs'. – Carl

Antwort

5

Sie Code funktioniert technisch. Es ist die Typ-Signatur, die dir hier Probleme bereitet.

Zunächst ist hier der Arbeitscode:

isElement :: (Eq a) => a -> [a] -> Bool 
isElement a [] = False 
isElement a (x:xs) = if a == x then True 
        else isElement a xs 

änderte ich zwei Dinge:

  1. Das erste, was im Auge zu behalten, wenn sie mit Haskells verkettete Listen (den Datentyp, die [] verwendet) arbeitet, ist dass sie nur Elemente desselben Typs enthalten können. In Ihrer Typignatur a ➞ [b] geben Sie jedoch an, dass Ihr erstes Element vom Typ a und die in Ihrer Liste vom Typ b, anders als a, sein müssen.
  2. Die zweite Sache ist auf Gleichheit überprüft mit generischen Typen „enable“ a und b und GHC werden Sie mit den Schritten eine Warnung zu folgen, um das zu beheben:

    • No instance for (Eq a) arising from a use of ‘==' 
        Possible fix: 
        add (Eq a) to the context of 
         the type signature for: 
         isElement :: a -> [a] -> Bool 
    

    Also, was es sagt wir sollen angeben, dass der a Typ verglichen werden kann!
    Und das ist fantastisch, weil wir dies vollständig tun können, indem wir den Compiler mit dem (Eq a) => Teil in unserem Code, der grob übersetzt in "gegeben diese Eigenschaft (Eq) des Datentyps a, [Typ Signatur hier einfügen"] den Schlüssel geben. (Fühlen sich frei, mich hier zu korrigieren, die Menschen von Stackoverflow!)

Ihr Code funktioniert, und Funktionen mit dieser Art von expliziter Rekursion Neuimplementierung ist, wie ich gelernt, wie man es in erster Linie gearbeitet, so zögern Sie nicht, um zu lernen, indem du die Sachen umschreibst, die du benutzt, dann schau dir ihre Quellen auf Hackage an, um zu sehen, wie reale Haskeller es tatsächlich tun.

Viel Spaß beim Lernen!

Verwandte Themen