Ich möchte ein Type Class
mit einigen Standardmethoden implementieren, aber ich erhalte einen Fehler, den ich innerhalb type classes
Definitionen nicht verwenden kann.Datensatz-Selektoren in Haskell's Type-Klassen
Der folgende Code im Grunde schafft die type class
add
Funktion definiert, die ein Element zum repr
Aufzeichnung einiger data type
hinzufügen sollten. Hier ist der Code:
import qualified Data.Graph.Inductive as DG
class Graph gr a b where
empty :: DG.Gr a b
empty = DG.empty
repr :: gr -> DG.Gr a b
-- following function declaration does NOT work:
add :: a -> gr -> gr
add el g = g{repr = DG.insNode el $ repr g}
Der Compiler wirft Fehler:
repr is not a record selector
In the expression: g {repr = DG.insNode el $ repr g}
In an equation for add:
add el g = g {repr = DG.insNode el $ repr g}
Ist es möglich, solche Verfahren in Haskell zu erklären?
Klärung
Ich brauche solches Design, weil ich einige data types
habe, die in simmilar Art und Weise verhalten. Sagen wir, wir haben A
, B
und C
data types
. Jede von ihnen sollte eine Aufzeichnung repr :: DG.Gr a b
haben, wobei a
und b
für jede von A
, B
und C
unterschiedlich sind.
A
, B
und C
teilen die gleichen Funktionen, wie add
oder delete
(die im Grunde Elemente hinzuzufügen oder löschen repr
aufnehmen). Wenn diese Datentypen viele Funktionen gemeinsam haben, ist es sinnvoll, die Funktionen in type class
zu implementieren und Instanzen dieser type class
zu machen - diese Funktionen werden automatisch für jede unserer data type
implementiert.
Weitere Ich würde gerne einige dieser data types
(lassen Sie uns sagen, ich möchte B
) verhalten sich geringfügig anders beim Aufruf add
Funktion darauf. Es ist einfach, dieses Verhalten zu implementieren, wenn instance
der type class
für B
gemacht wird.
Die Antwort „nein“ ist, aber "irgendwie, mit Linsen", aber noch wichtiger, ich fühle, dass es ein grundlegendes Missverständnis darüber gibt, wofür Klassen hier irgendwo sind. Es würde viel helfen, wenn Sie sagten, warum Sie solch eine Klasse haben wollen; wir können vielleicht eine idiomatische Alternative vorschlagen. –
@DanielWagner - Ich habe eine Klärung für das Problem hinzugefügt, das ich versuche zu lösen - ich hoffe, es ist jetzt genug klar, warum ich versuche, dies zu tun :) –
Siehe meine aktualisierte Antwort. Im zweiten Beispiel verwende ich 'update' Methode, die die eigentliche Aktualisierung durchführt (kann unter Verwendung dieser Datensatzaktualisierungssyntax in Instanzen implementiert werden), und das dritte Beispiel verwendet' Control.Lens'. – JJJ