2013-04-22 8 views
12
isPalindrome :: [a] -> Bool 
isPalindrome xs = case xs of 
         [] -> True 
         [x] -> True 
         a -> (last a) == (head a) && (isPalindrome (drop 1 (take (length a - 1) a))) 

main = do 
    print (show (isPalindrome "blaho")) 

Ergebnisse inHaskell: keine Instanz für (Eq a) die sich aus einer Verwendung von `==‘

No instance for (Eq a) 
    arising from a use of `==' 
In the first argument of `(&&)', namely `(last a) == (head a)' 
In the expression: 
    (last a) == (head a) 
    && (isPalindrome (drop 1 (take (length a - 1) a))) 
In a case alternative: 
    a -> (last a) == (head a) 
     && (isPalindrome (drop 1 (take (length a - 1) a))) 

Warum wird dieser Fehler auftritt?

+1

Ihre Funktion geht davon aus, dass 'a' mit' == 'verglichen werden kann, Sie müssen diese Information in die Typensignatur eingeben. –

+0

Weil '(==)' ein Mitglied der 'Eq' Klasse ist. Sie können es also nur für Typen verwenden, die Instanzen von 'Eq' sind. –

+1

Real world haskell chap 3? Ich auch! – Jason

Antwort

27

Sie vergleichen zwei Artikel des Typs a mit ==. Das bedeutet, a kann nicht irgendein Typ sein - es muss eine Instanz von Eq sein, da der Typ ==(==) :: Eq a => a -> a -> Bool ist.

Sie können dieses Problem beheben, eine Eq Einschränkung für a die Art Signatur Ihrer Funktion durch Zusatz:

isPalindrome :: Eq a => [a] -> Bool 

By the way, gibt es eine viel einfachere Art und Weise ist diese Funktion verwendet reverse zu implementieren.

+8

Laut Lambdabot ist 'isPalindrome = reverse >> = (==)': D – fredoverflow

+1

@FredOverflow Wow, das ist verrückt obskur. :) – augustss

+1

Es verwendet die Monad-Instanz für Funktionen, genau wie 'Join (+) 2 = 4'. Aber 'isPalindrome xs = xs == reverse xs' ist völlig in Ordnung. –

0

hammar Erklärung ist korrekt.

Ein weiteres einfaches Beispiel:

nosPrimeiros :: a -> [(a,b)] -> Bool 
nosPrimeiros e [] = False 
nosPrimeiros e ((x,y):rl) = if (e==x) then True 
             else nosPrimeiros e rl 

Die (e == x) wird für diese Funktion Signatur fehlschlagen. Sie müssen ersetzt werden: für eine

nosPrimeiros :: Eq => a -> [(a,b)] -> Bool 

nosPrimeiros :: a -> [(a,b)] -> Bool 

Hinzufügen einer Gleichung Instanz Diese Instanziierung sagt, dass jetzt, ein eine Art hat, dass mit vergleichbar sein kann, und (e == x) wird nicht fehlschlagen.

Verwandte Themen