Ich versuche, eine Instanz von Enum für den folgenden Typ zu schreiben:
%Vor%Das funktioniert gut für:
%Vor%Scheitert aber für:
%Vor%Mit dem Fehler:
%Vor%Ich verstehe den Fehler. Meine Fragen sind: Wie schreibt man die Enum-Instanz korrekt, um diese Aufzählung durchzuführen? Ist es möglich? Vor allem: Ist es eine gute Übung?
Ihr Problem ist, dass Pitch
implizit begrenzt ist - d. h. es hat ein geringstes und größtes Element -, aber Sie spiegeln diese Beschränktheit in Ihrem Code nicht wider. Der Code
desugars zu
%Vor% wodurch succ
der generierten Werte beibehalten wird, bis succ
s Pitch O3 F
und explodiert. Wie konnte es wissen, dass es dort aufhören sollte?
Aus der Prelude-Dokumentation :
Für jeden Typ, der eine Instanz der Klasse
Bounded
sowie Enum
, das Folgende sollte halten:...
%Vor%
enumFrom
undenumFromThen
sollte mit definiert werden eine implizite Grenze, also:
Um dieses Problem zu beheben, fügen Sie einfach
hinzu %Vor%und fügen Sie dann den Code aus der Dokumentation hinzu:
%Vor%und jetzt [Pitch O1 A ..] stoppt am Ende:
%Vor% Randnotiz: Sie können einzelne Aufrufe von div
und mod
durch Mustervergleich bei einem einzelnen Aufruf von divMod
: x 'divMod' y == (x 'div' y, x 'mod' y)
ersetzen. (Für streng positive Zahlen wie diese glaube ich, dass ich gehört habe, dass quotRem
möglicherweise eine bessere Wahl ist; quot
und rem
sind wie div
und mod
, aber mit unterschiedlichen zeichenbezogenen Verhaltensweisen. ) Außerdem könnten Sie Ihre 6
s durch 1 + (fromEnum (maxBound :: Note))
ersetzen, um zu vermeiden, dass die Zahl versehentlich falsch eingegeben wird.
[x ..]
wird in die Methode enumFrom x
entuugariert, für die prelude bietet die folgende Standardimplementierung :
Überschreiben Sie es, um das Richtige für Ihre Instanz zu tun. Wahrscheinlich möchten Sie auch enumFromThen
aus ähnlichen Gründen überschreiben.
Tags und Links haskell