Typerweiterung für diskriminierte Union in F #

8

Ich habe die folgende diskriminierte Verbindung definiert:

%Vor%

Dann habe ich eine hübsche Druckfunktion wie folgt erstellt:

%Vor%

Nun möchte ich, dass mein Expr -Typ diese Funktion für die Methode ToString() verwendet. Zum Beispiel:

%Vor%

Aber ich kann das nicht, weil stringify noch nicht definiert ist. Die Antwort ist, Stringify als Mitglied von Expr zu definieren, aber ich möchte meine ursprüngliche Typdeklaration nicht mit dieser spezialisierten Methode verschmutzen, die mit der Zeit weiter wachsen wird. Daher entschied ich mich, eine abstrakte Methode zu verwenden, die ich mit einer Erweiterung des intrinsischen Typs weiter unten implementieren konnte in der Datei. Folgendes habe ich getan:

%Vor%

Aber ich bekomme den folgenden Compilerfehler:

  

Fehler FS0912: Dieses Deklarationselement ist in einem nicht erlaubt   Vergrößerung

Die Nachricht scheint nicht einmal richtig zu sein (ich erstelle noch keine Art Augmentation), aber ich verstehe, warum sie sich beschweren. Es will nicht, dass ich ein abstraktes Mitglied in einem diskriminierten Unionstyp erstelle, weil es nicht vererbt werden kann. Obwohl ich wirklich keine Vererbung möchte, möchte ich, dass sie sich wie eine partielle Klasse in C # verhält, wo ich sie woanders definieren kann (in diesem Fall die gleiche Datei).

Ich habe "betrogen", indem ich die spätbindenden Eigenschaften des Attributs StructuredFormatDisplay zusammen mit sprintf :

verwendet habe %Vor%

Obwohl nun sprintf und ToString beide den gleichen String ausgeben, gibt es keine Möglichkeit, den Add (Con 2,Con 3) Output im Gegensatz zu (2 + 3) zu erhalten, wenn ich es möchte.

Gibt es eine andere Möglichkeit zu tun, was ich versuche?

P.S. Ich habe auch festgestellt, dass es nicht funktioniert, wenn ich das Attribut StructuredFormatDisplay anstelle des Originaltyps auf die Augmentation setze. Dieses Verhalten scheint mir nicht richtig zu sein. Es scheint, dass entweder der F # -Compiler das Attribut zur Typdefinition hinzufügen oder Attribute bei Typerweiterungen verbieten sollte.

    
luksan 03.08.2013, 18:59
quelle

3 Antworten

5

Tatsächlich muss stringify mit dem Datentyp wachsen , andernfalls würde es zu einer unvollständigen Musterübereinstimmung kommen. Jede wesentliche Änderung des Datentyps würde auch die Änderung von stringify erfordern. Als persönliche Meinung würde ich darüber nachdenken, beide am selben Ort zu behalten, es sei denn, das Projekt ist wirklich komplex.

Da Sie jedoch bevorzugen, dass Ihr DU-Typ eindeutig ist, sollten Sie den Datentyp in einen DU-Fall einbetten:

%Vor%

Zitat aus dieser Antwort :

  

In komplexen Programmen erleichtern eindeutige Typ-Signaturen die Aufrechterhaltung der Zusammensetzbarkeit.

     

Nicht nur das Hinzufügen von mehr Fällen zu Einzelfall-DUs ist einfacher, es ist auch einfacher, DUs mit Member- und statischen Methoden zu erweitern.

    
bytebuster 04.08.2013, 13:51
quelle
8

Haben Sie in Betracht gezogen, Ihre ToString in der Augmentation zu definieren?

%Vor%

Allerdings hat die hässliche Nebenwirkung eines

%Vor%     
Daniel Fabian 03.08.2013 22:28
quelle
6

Wie wäre es mit einer Lösung, die nicht einmal eine Typendung benötigt?

Definieren Sie stattdessen einen Typ mit einem statischen Member, der stringify ist (wir benötigen den Dummy-Typ als type a ... and b erfordert b als Typ

%Vor%     
John Palmer 03.08.2013 22:20
quelle