Neue Typen werden häufig verwendet, um das Verhalten bestimmter Typen zu ändern, wenn sie in bestimmten Klassenkontexten verwendet werden. Zum Beispiel würde man den Data.Monoid.All
-Wrapper verwenden, um das Verhalten von Bool
zu ändern, wenn es als Monoid
verwendet wird.
Ich schreibe gerade einen solchen Wrapper für den neuen Typ, der für eine große Anzahl verschiedener Typen gelten würde. Der Wrapper soll das Verhalten einer bestimmten Klasseninstanz ändern. Es könnte so aussehen:
%Vor% Durch das Hinzufügen dieses Wrappers ändert sich jedoch häufig die Verwendbarkeit des umschlossenen Typs. Wenn ich zum Beispiel zuvor die Funktion mconcat :: Monoid a => [a] -> a
verwenden konnte, kann ich sie jetzt nicht für eine Liste umgebender Werte verwenden.
Ich kann natürlich -XGeneralizedNewtypeDeriving
und newtype Wrapper a = Wrapper a deriving (Monoid)
verwenden. Dies löst jedoch nur das Problem für Monoid
und keine andere Klasse, während ich mich mit einer offenen Welt voller verschiedener Klassen befasse, und eine eigenständige generische Neugenerierung von Orphan ist nicht wirklich eine praktische Option. Idealerweise würde ich gerne deriving hiding (Special)
schreiben (was jede Klasse außer Special
ableitet), aber das ist natürlich nicht gültig. Haskell, natürlich.
Gibt es eine Möglichkeit, dies zu tun, oder bin ich nur verrückt und muss eine GHC-Feature-Anfrage hinzufügen?
Sehen Sie, GeneralizedNewtypeDeriving
ist unsicher . In diesem Sinne ist hier eine unsichere Art, es zu tun
Sie können es dann jederzeit verwenden, wenn Sie die typeclass-Instanz benötigen
%Vor%Dieses System der Weitergabe von expliziten Wörterbüchern ist sehr allgemein und hat eine ziemlich gute (wenn auch experimentelle) Bibliothek, die es unterstützt, mit dem Namen Data.Constraint
Ich fürchte, es gibt keinen direkten Weg, wie man das in GHC macht. Aber ich denke, du könntest dein Problem mit Template Haskell lösen.