2012-04-14 3 views
13

Ich definiere eine monadische beobachtbare/reaktive Parser. Dies verhält sich anders als ein normaler Parser, da es sich um eine kontinuierliche Abfrage handelt. Der zugrunde liegende Typ ist:Zweck eines Einzelfall diskriminierten Union

IObservable<'a> -> IObservable<'b> 

Von an verschiedenen Parser-Implementierungen in funktionalen Sprachen suchen, es scheint, als ob der geeignetere Weg, Dinge zu definieren ein einziger Fall diskriminierte Vereinigung ist:

type Pattern<'a,'b> = Pattern of (IObservable<'a> -> IObservable<'b>) 

Was bedeutet, dass ich dann müssen die zugrunde liegende Funktion zu extrahieren, es zu benutzen:

let find (Pattern p) = p 

die Frage ist: ist das nur durch Konvention, oder zum Zweck der späteren Erweiterung oder ist Gibt es einen Grund, dies zu tun, auch wenn sich die Definition niemals ändert?

Bonus Frage: Wenn es nur für eine bequemere Art Signatur ist, warum nicht nur eine Art Alias:

type Pattern<'a,'b> = IObservable<'a> -> IObservable<'b> 

ich ziemlich weit durch diese vorgeschoben haben, und haben keinen Fall gefunden, wo die Zusammensetzbarkeit wird beeinflusst, wenn das DU nicht verwendet wird.

Antwort

14

F # -Compiler erhalten keine Informationen über die Art Abkürzung, so dass Sie von Typinferenz nicht profitieren überhaupt. Die Typensignatur kann als Programmspezifikation verstanden werden; Lassen Sie den Typ Checker ihre Arbeit tun, ist ein guter Weg, um die Richtigkeit Ihrer Programme zu gewährleisten.

Sie müssen explizit Typenannotation überall im Fall von Typ alias angeben:

type Vector = float * float 

// val add : float * float -> float * float -> Vector 
let add ((x1, y1): Vector) ((x2, y2): Vector): Vector = (x1 + y1, x2 + y2) 

aber es nicht geben Ihnen Transparenz als DUs mit:

type Vector = V of float * float 

// val add : Vector -> Vector -> Vector 
let add (V(x1, y1)) (V(x2, y2)) = V(x1 + y1, x2 + y2) 

In komplexen Programmen klar Typ Signaturen in der Tat wird es leichter, die Kompatibilität zu erhalten.

Nicht nur das Hinzufügen von mehr Fällen zu Einzelfall-DUs ist einfacher, sondern es ist auch einfacher, DUs mit Member- und statischen Methoden zu erweitern. Ein Beispiel ist, dass Sie oft ToString() für schönes Drucken überschreiben.

+0

Danke, das ist eigentlich ein ziemlich konkreter Grund. Definitiv möchte nicht tippen "IObservable <'a> -> IObservable <'b>' überall anstelle von 'Muster <'a,'b>'. – yamen

+1

Ein Follow-up viele Monde später. Ich habe der Union einen zweiten Fall hinzugefügt, und somit ist das Universum im Gleichgewicht. – yamen

0

Von dem, was ich verstehe, diskriminierter Einzelfall Unterscheidungstyp gibt es einen Namen, der für Ihre Problemdomäne semantisch relevant ist, zu einem sonst allgemeinen Zweck Back-End-Typ, dessen Name "Zeichenfolge" ist.

Es ist ein Licht Abstraktion Leckage Fix für Semantik, und nur das, AFAIK

+0

Ich glaube nicht, dass das stimmt. Das ist ein Typ-Alias. Eine einzelne diskriminierte Union ist eine vollständige Klasse und in diesem Fall wird eine Funktion umbrochen (oder delegiert in C# -Talk). – yamen

+0

in der Tat. aber ich weiß keine andere Verwendung als das ... auch, beachten Sie, dass Sie einige Methoden zu Unionstypen hinzufügen können. – nicolas