Frage

Ich habe die folgenden Funktionen:

which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
    | x > y      = worker y ys
    | otherwise  = worker x ys

und frage mich, wie ich die Typen der oben genannten Funktionen definieren sollte which und worker?

Zum Beispiel, welche der folgenden Wege wäre am besten als Geben Sie Signatur ein Für Arbeiter?

worker :: Num a => a -> [a] -> a,

oder

worker :: Ord a => a -> [a] -> a?

Ich bin nur sehr verwirrt und verstehe nicht, welche drei ich wählen sollte. Ich würde mich über Ihre Gedanken freuen. Vielen Dank.

War es hilfreich?

Lösung

Wenn Sie die Funktion ohne explizite Typ Signatur definieren, schließt Haskell die allgemeinste. Wenn Sie sich nicht sicher sind, ist dies der einfachste Weg, um herauszufinden, wie Ihre Definition gelesen wird. Sie können es dann in Ihren Quellcode kopieren. Ein häufiger Fehler besteht darin, eine Funktion falsch einzugeben und dann einen verwirrenden Typenfehler woanders zu erhalten.

Wie auch immer, Sie können Informationen über die erhalten Num Klasse durch tippen :i Num in GHCI oder durch Lesen der Dokumentation. Das Num Klasse gibt es dir +, *, -, negate, abs, signum, fromInteger, sowie jede Funktion von Eq und Show. Beachte das < und > sind nicht da! Erfordernis Werte von Num Und der Versuch, sie zu vergleichen, erzeugt tatsächlich einen Typfehler - nicht jede Art von Zahl kann verglichen werden.

So sollte es sein Ord a => ..., wie Num a => ... würde einen Typfehler erzeugen, wenn Sie es ausprobieren würden.

Andere Tipps

Wenn Sie darüber nachdenken, was Ihre Funktionen tun, werden Sie das sehen which xs Gibt den Mindestwert in zurück in xs. Was kann einen Mindestwert haben? Eine Liste von etwas Orderable!

Fragen Sie GHCI und sehen Sie, was es sagt. Ich habe gerade Ihren Code in eine Datei kopiert und in GHCI geladen. Dann benutzte ich :t Dies ist ein spezieller GHCI -Befehl, um die Art von etwas zu bestimmen.

ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a

Haskells Typ -Inferenz ist in den meisten Fällen ziemlich klug. Lerne es zu vertrauen. Andere Antworten decken ausreichend ab, warum Ord sollte in diesem Fall verwendet werden; Ich wollte nur sicherstellen, dass GHCI eindeutig als Technik zur Bestimmung der Art von etwas erwähnt wurde.

Ich würde immer mit der ord Typenbeschränkung gehen. Es ist der allgemeinste, also kann es öfter wiederverwendet werden.

Die Verwendung von Num gegenüber ORD hat keinen Vorteil.

INT kann einen kleinen Vorteil haben, da es nicht polymorph ist und keine Wörterbuchsuche benötigt. Ich würde ord ord verwenden und das spezialisierte Pragma verwenden, wenn ich für die Leistung benötigt würde.

Bearbeiten: Ich habe meine Antwort nach Kommentaren geändert.

Es hängt davon ab, was Sie vergleichen möchten. Wenn Sie vergleichen können Double, Float, Int, Integer und Char dann benutze Ord. Wenn Sie nur vergleichen können Int Dann benutze einfach Int.

Wenn Sie ein anderes Problem wie dieses haben, schauen Sie sich einfach die Instanzen der Typklasse an, um zu sagen, welche Typen Sie in der Funktion verwenden möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top