2009-06-08 4 views
3

Ok, kann mir jemand erklären, warum F # Ihnen erlaubt, die Operatoren> und^zu überladen, aber nicht erlaubt, sie zu benutzen?F # und Operator Überladungen: (>) und (^)

Wenn ich meinen F # -Code als Bibliothek kompiliere und diese Operatoren von VB verwende, funktionieren alle. Wenn ich diese Operatoren aus C# verwende, funktionieren alle außer op_Concatenate (wie erwartet). Aber F # ignoriert nicht nur einige von ihnen, der statische Typ-Checker sagt Ihnen nicht einmal, dass er dies plant.

bearbeiten Codebeispiel

type OppTest4(value: int) = 
    member this.value = value 
    static member (^) (left : OppTest4, right : OppTest4) = 
    OppTest4(Int32.Parse(left.value.ToString()^right.value.ToString() )) 
    static member (+) (left : OppTest4, right : OppTest4) = 
    OppTest4(left.value + right.value) 
    static member (>) (left : OppTest4, right : OppTest4) = 
    left.value > right.value 
    static member (<) (left : OppTest4, right : OppTest4) = 
    left.value < right.value 

Antwort

4

F # default Bedeutungen für diesen Operator Symbole hat, die für F # vernünftig ist. Sie können jederzeit Ihre eigenen Bedeutungen definieren, die die Standardeinstellung Schatten, a la

let (>) x y = ... 

Zum Beispiel Sie diesen Operator definieren könnten „T.operator> (U)“ bedeuten (x unter der Annahme, T Typ und y geben U).

Siehe prim-types.fs in FSharp.Core in der Quelldistribution für die Standarddefinitionen. (Sie sind nicht-trivial!)

Gegeben die Kombination von (1) fehlender Unterstützung für einen typenklassenähnlichen Mechanismus auf der CLR (um gemeinsame Semantik unter einer Reihe von ansonsten nicht verwandten Typen zu definieren) und (2) die Tatsache, dass primitive Typen (wie 'int') häufig für jede Programmiersprachenimplementierung speziell sein müssen (zB System.Int32 definiert keine Operator + -Methode, aber die meisten Programmiersprachen verhalten sich so, als ob eine solche Methode existiert), Es ist heute schwer vorstellbar, dass allgemein interoperable Operator-Funktionen in allen Sprachen von .NET vorhanden sind. Es gibt eine Menge Design-Kompromisse, abhängig davon, was genau eine Sprache tut (zu viele interagierende Probleme, die hier zusammengefasst werden). In jedem Fall sollten Sie in der Lage sein, eine beliebige Methode aus F # aufzurufen, und wenn das Verhalten des Standardoperators unerwünscht ist, können Sie die Operatoren für die gewünschten Verhaltensweisen neu definieren (Schatten). Wenn es ein bestimmtes Szenario gibt, dass Sie Probleme haben, Arbeit zu machen, lassen Sie es mich wissen.

EDIT

ich genauer an

http://cs.hubfs.net/forums/thread/10869.aspx

+0

Ok, warum funktioniert das dann nicht? "static member (>) (links: OppTest4, rechts: OppTest4) = left.value> right.value" –

+0

> es ist heute schwer vorstellbar, allgemein interoperable Operator-Funktionen in allen Sprachen auf .Net zu verwenden.

+0

Ich wäre neugierig auf, ob ich die Standard-Operatordefinition nur für einen Typ mit einer Let-Bindung Schatten - ich habe keine Kontrolle über die Typ-Implementierung. Wenn ja, wie würde das geschehen? Ich habe versucht, lassen (>) (a: SomeType) (b: SomeType) = ... aber dann hat jeder Vergleich zwischen anderen Typen brach, so dass 2> 1 nicht mehr kompilieren. – em70

0

Ich bin damit einverstanden, gibt es hinzugefügt Inkonsistenz: Operator definiert werden kann, kann aber nicht verwendet werden.

Fragen Sie, warum F # -Designer entschieden haben, einen Vergleich mit der System.IComparable-Schnittstelle anstelle einer Überlastung der Operatoren zu implementieren? Ich weiß nicht warum, aber in der OO-Sprache würde ich IComparable bevorzugen, anstatt die Operatoren zu überladen. Also würde ich F # -Entwicklern empfehlen, die C# -Kompatibilität zu brechen und "statische Member (>) (...)" -Syntaxzucker zu verbieten.

Wenn Sie fragen, wie diese überladenen Operatoren aufgerufen werden, ist es ziemlich einfach: Verwenden Sie statische Mitglieder op_Concatenate, op_GreaterThan oder op_LessThan. (Wirklich, ich habe eine Compiler-Warnung, die das Problem beschreibt. F # 1.9.6.16)

Runtime Fehler Casting zu System.IComparable ohne Compiler-Warnung ist definitiv ein Fehler. Sie können es an [email protected] senden.

+0

Der Laufzeitfehler ist kein Fehler, es ist von Design.Ich habe eine öffentliche Diskussion über dieses Design jedoch nicht gesehen, die gut motiviert ist, auch wenn nicht offensichtlich, so werde ich versuchen, das bald zu beheben. – Brian

+0

Ok, es ist unmöglich zu beweisen, dass jeder Instanz von OppTest4 hat keine IComparable Schnittstelle Aber es ist immer noch bekannt, dass es OppTest4 Instanzen gibt, die nicht nach IComparable umgewandelt werden können! Also muss es mindestens eine Warnung geben! Warum nicht? – vpolozov

+0

@ .vpolozov.name : Es scheint, dass Abschnitt 9.6 der F # -Spezifikation (http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec2.aspx) anzeigt, dass sie erwägen, w hinzuzufügen in bestimmten Situationen, in denen die Verwendung der Vergleichsoperatoren wahrscheinlich fehlschlägt. – kvb