2012-04-01 3 views
1

Ich versuche, eine Haskell-Funktion zu schreiben, die überprüft, ob eine Liste von ganzen Zahlen ist ohne eine der bereits vorhandenen Funktionen zu verwenden, um die Reihenfolge der Liste zu bestellen oder zu überprüfen. Ich habe den folgenden Code geschrieben, aber ich verstehe nicht, warum es nicht funktioniert. Ich bekomme den Fehler:Haskell benutzerdefinierte isordered Funktion, um eine Liste der Ganzzahlen zu überprüfen

No instance for (Ord integer) 
     arising from a use of `<=' 
    In the expression: x <= (head xs) 

Ich verstehe nicht, was das bedeutet. Gibt es eine andere Art, dass ich diese Funktion schreiben sollte? Hier ist mein Code soweit.

isordered :: [integer] -> Bool 
isordered [] = True 
isordered (x:[]) = True 
isordered (x:xs)|x <= (head xs) = isordered xs 
       |otherwise = False 

Vielen Dank im Voraus !!!

+7

Es sollte 'Integer', nicht' integer' sein. –

Antwort

8

In Haskell beginnen Typennamen mit Großbuchstaben und Typvariablen beginnen mit Kleinbuchstaben. Wenn Sie also integer schreiben, ist das eine Typvariable. Ihr Typ ist also derselbe wie [a] -> Bool, d. H. Sie nehmen eine Liste von allem und geben ein Bool zurück. Da es keine Beschränkung für den Typ des Elements in der Liste gibt, dürfen Sie <= nicht verwenden.

Um dies zu beheben, können Sie entweder ändern Sie es einfach auf Integer, was Sie wollten, oder fügen Sie eine Ord-Einschränkung wie folgt hinzu: Ord a => [a] -> Bool. Letzteres bewirkt, dass Ihre Funktion mit jedem Typ funktioniert, der die Typenklasse Ord implementiert (die Vergleichsoperatoren wie <= bereitstellt).

+0

Ah brilliant !! Ich wusste, dass es etwas Dummes war, was ich tat !!! – chefburns

3

Was genau gilt als "bereits bestehende Funktion"?

isordered xs = all (uncurry (<=)) $ zip xs (tail xs) 

Weitere Low-Level ist

isordered (x:y:zs) = x <= y && isordered (y:zs) 
isordered _ = True 
+0

Alle vorhandenen Bibliotheksfunktionen, die das Sortieren oder Ordnen beinhalten, wären besser zu sagen! In Ihrer mehr Low-Level-Funktion gibt es das nicht immer wahr? – chefburns

+3

Ich würde das schreiben: 'isOrdered xs = und $ zipWith (<=) xs tail xs', um diese Unruhe zu vermeiden. – Jedai

+0

@Jedai: Ja, sieht besser aus. – Landei

0

Ein anderer Weg, es zu tun Wachen mit:

isOrdered :: Ord a => [a] -> Bool 
isOrdered (x:y:xs) | x<=y = isOrdered (y:xs) 
        | otherwise = False 
isOrdered _ = True