Ableiten von Standardinstanzen mit GHC.Generics

8

Ich habe eine Typklasse Cyclic , für die ich generische Instanzen bereitstellen möchte.

%Vor%

Gegeben eine Summenart von Nullkonstruktoren,

%Vor%

Ich möchte eine Instanz erzeugen, die dieser entspricht:

%Vor%

Ich habe versucht, die erforderliche Generic -Maschinerie wie folgt auszuarbeiten

%Vor%

Jetzt kann ich Standardimplementierungen für Cyclic mit GCyclic :

bereitstellen %Vor%

aber meine GCyclic Instanzen sind falsch. Verwenden von T3 von oben

%Vor%

Es ist klar, warum rot hier id entspricht. grot berechnet die (:+:) -Struktur von T3 erneut, bis sie den Basisfall grot U1 = U1 erreicht.

Es wurde in #haskell vorgeschlagen, Konstruktorinformationen von M1 zu verwenden, damit grot den nächsten Konstruktor auswählen kann, auf den man rekursiv zugreifen kann, aber ich bin nicht sicher, wie ich das machen soll.

Ist es möglich, die gewünschten Instanzen von Cyclic mit GHC.Generics oder einer anderen Form von Scrap Your Boilerplate zu erzeugen?

BEARBEITEN: Ich könnte Cyclic mit Bounded und Enum

schreiben %Vor%

aber (wie es ist) ist dies unbefriedigend, da es alle Bounded , Enum und Eq erfordert. Darüber hinaus kann Enum in einigen Fällen nicht automatisch von GHC abgeleitet werden, wohingegen Generic robuster ist.

    
cdk 03.04.2014, 23:39
quelle

1 Antwort

5

Bearbeitet nach dem erneuten Lesen, was ord bedeuten soll, und erneut versuchen, die Produkt von zwei Zyklen Problem

Sie können herausfinden, wann Sie zur anderen Seite einer Summe von Konstruktoren gehen müssen, wenn Sie wissen, dass das, was drin ist, bereits beim letzten Konstruktor ist, was die neuen Funktionen end und gend tun. Ich kann mir keine zyklische Gruppe vorstellen, für die wir end nicht definieren können.

Sie können gord für Summen implementieren, ohne die Werte zu prüfen. Die Erweiterung ScopedTypeVariables hilft dabei. Ich habe die Signaturen geändert, um Proxies zu verwenden, da Sie nun undefined mischen und versuchen, einen Wert in Ihrem Code zu dekonstruieren.

%Vor%

Hier ist die Cyclic Klasse mit end , defaults und Integral n (anstelle von Int ) für ord

%Vor%

Und die Klasse GCyclic und ihre Implementierungen:

%Vor%

Ich kann nicht genug betonen, dass das Folgende eine Äquivalenzklasse über mehrere zyklische Untergruppen des Produktes der zwei Zyklen macht. Aufgrund der Notwendigkeit, Enden für Summen zu erkennen, und das Gesicht, dass die Berechnungen für lcm und gcm nicht faul sind, können wir nicht mehr Spaß machen, wie eine zyklische Instanz für [a] abzuleiten.

%Vor%

Hier sind einige weitere Beispiele:

%Vor%

Und ein paar Beispielcode zum Ausführen:

%Vor%

Das vierte und fünfte Beispiel zeigen, was passiert, wenn wir eine Instanz für das Produkt zweier zyklischer Gruppen erstellen, deren Ordnungen nicht gleichzeitig sind.

    
Cirdec 04.04.2014, 00:36
quelle