2009-06-08 7 views
4

Ich habe kürzlich versucht, etwas in F # schreiben mit Microsoft Solver Foundation Services und dabei stieß ich auf ein Problem: Ich musste eine Bedingung (Term> Term), die in C# einfach sein könnte ausgedrückt als t1> t2 und gibt ein anderes Term-Objekt zurück. In F # musste ich stattdessen Term.op_GreaterThan aufrufen, um das gleiche Ergebnis zu erzielen, als würde t1> t2 einen bool ergeben und keinen Ausdruck.
Jetzt frage ich mich, warum ist F # nur op_GreaterThan, wenn es einen booleschen ergibt? Und welche Bedeutung hätte F # 's Interpretation von t1> t2, während Term IComparable nicht implementiert?
Bitte beachten Sie, dass ich verstehe, warum so etwas mit Gleichheit und die gesamte Gleichheit auf der Grundlage struktureller Vergleich zu tun, ich verstehe einfach nicht, wie das auf "größer als"/"kleiner als" Vergleiche erweitert werden könnte.F # und op_GreaterThan

+0

Siehe auch http://cs.hubfs.net/forums/thread/10860.aspx und http://stackoverflow.com/questions/967508/f-and-operator-overloads – Brian

Antwort

4

Lehrbuch Antwort:

Betreiber Überlastung nicht Teil der Common Language Specification ist, was bedeutet, Compiler Schriftsteller sind frei, zu ignorieren oder sie nur teilweise unterstützen, wenn sie Lust haben. Als Autor/in einer Bibliothek sind Sie dafür verantwortlich, alternative Möglichkeiten bereitzustellen, damit Menschen mit der Klasse arbeiten können.

Pragmatische Antwort:

Weil es eine dumme Sache, in erster Linie zu tun ist. Die Methode op_GreaterThan wurde explizit erstellt, um Vergleiche zu erstellen. Dass es, du sollst nicht 'interessante' Dinge damit machen, wie zwei Begriffe miteinander zu verbinden. Die CLR lässt Sie nur missbrauchen, weil sie ältere Sprachen wie C++ unterstützen muss.

Übrigens gibt es eine Überlastung speziell für die Verbindung zweier Dinge zusammen. Es heißt op_Concatenate. Sie sollten wirklich überlegen, es anstelle von op_GreaterThan zu verwenden.

EDIT

Fast Gute Antwort:

In F # das Verketten Operator I erwähnt ist ^.

Ich nenne das die fast-gute Antwort, weil ich nicht so sicher bin, dass C# es unterstützt. Ich denke es ist nur in VB und F # erlaubt.

EDIT # 2

Es scheint, F # nicht die^Überlastung schließlich ehrt.

EDIT # 3

WTF ist hier los? F # berücksichtigt den Operator> überhaupt nicht. Sicher können Sie es überladen, und es wird die op_GreaterThan-Methode korrekt ausgeben, aber es ignoriert es. Es versucht nicht einmal, op_GreaterThan zu verwenden, stattdessen sucht es nach der System.IComparable-Schnittstelle.

Noch schlimmer, dies ist eine Laufzeitprüfung. Obwohl es statisch feststellen kann, dass Klasse Foo IComparable nicht implementiert, geht es trotzdem weiter und kompiliert den Code sowieso.

+1

Und natürlich, wenn nichts anderes, könnten Sie Ihren eigenen F # -Operator definieren, der Term.op_GreaterThan explizit aufruft. –

+0

Ich mache nicht wirklich irgendeine Verkettung, aber Ihre Antwort klärt ziemlich die Designwahl auf. Ich verstehe immer noch nicht die Bedeutung von Term> Term, wenn es wirklich keine Möglichkeit gibt, dass der F # -Compiler ihm eine vernünftige Bedeutung geben könnte, ohne op_GreaterThan zu verwenden, aber zumindest bekomme ich die Sprachdesign-Wahl – em70

+0

@Joel, Kannst du? Aus meiner Forschung kann man> in F # überladen, aber man kann es nicht konsumieren. Es ignoriert nur die Überladung und sucht stattdessen nach IComparable. –

2

Intuitiv sollte ein Vergleichsoperator wie > immer einen booleschen Wert ergeben!

Sie können die Frage a > b mit Ja oder Nein beantworten, aber nicht mit 3 oder new Stopwatch().

Wenn es irgendetwas anderes, so etwas wie

if a < b then 

zurückkehren könnte, würde keinen Sinn mehr machen.

F # -Objekte (Tupel, Listen usw.) implementieren oft IComparable oder IStructuralComparable, die zum Beispiel ein Tupel lexikographisch sortieren können.

* Hinweis:

IMHO, es ist nicht die beste Lösung erlaubt zu werden alle Objekte zu vergleichen und dann Ausnahmen zur Laufzeit werfen. Haskell hat das besser mit Typklassen gelöst.

greater :: (Ord a) => a -> a -> Bool 
greater a b = a < b 

Das Vergleichen von nicht kompatiblen Typen würde bei der Kompilierung fehlschlagen.

+0

Ich bekomme die Tatsache, dass von a Aus sprachlicher Sicht macht es Sinn, a> b einen Booleschen Wert zu erhalten, aber .NET erlaubt es, op_GreaterThan als ('a *' b) -> 'c zu definieren, also würde die Interoperabilität in diesen Fällen keine vernünftige Kompatibilität nahelegen anwesend sein? (Vor allem, weil der Fall, den ich in Betracht ziehe, eine Microsoft-Bibliothek ist ...) – em70

0

Sie müssen die Operatoren < und> nicht verwenden. Die Solver Foundation Services-Modellklasse verfügt über Greater und Less-Methoden. Sie sollten diese stattdessen verwenden können.