Ich habe einen Fibonacci Sequenzgenerator wie folgt implementiert
%Vor%und mein Testcode ist
%Vor%Der Test ist fehlgeschlagen und das Druckergebnis ist
Erwartet: [0; 1; 1; 2; 3; 5; 8; 13] Ergebnis: seq [0; 1; 1; 2; ...] Ergebnis Länge: 8
Wenn ich eine for-Schleife verwendet habe, um jedes Element im Ergebnis zu drucken, habe ich exakt die gleichen Elemente in der erwarteten Reihenfolge erhalten.
Was ist also der Unterschied zwischen der erwarteten und der Ergebnissequenz?
Bearbeiten: Meine Implementierung kann unter Ссылка
gefunden werdenBearbeiten: Beantworten von John Palmers Antwort Ich habe gerade einen Test in F # interaktives Fenster geschrieben %Vor%
Das Ergebnis, das ich habe, ist val a: seq = [1; 2; 3] val b: seq = [1; 2; 3] val c: bool = wahr
So kann F # Strukturvergleiche auch mit Sequenzen durchführen.
Bearbeiten, um die Antwort von Gene Belitski zu reflektieren Ich habe den Test in
geändert %Vor%Und es hat jetzt funktioniert. Vielen Dank! aber ich verstehe immer noch nicht, warum eine einfache seq [1; 2; 3] = seq [1; 2; 3] funktioniert, aber mein Testfall nicht.
Während Sie erwarten können, dass a=b
Elemente für Sequenzen vergleicht, berechnet a=b
die Referenzgleichheit.
Sie können dies mit etwas wie
sehen %Vor%was false zurückgibt.
In einigen Fällen, in denen Sie Konstanten verwenden, erhalten Sie jedoch verwirrende Ergebnisse, insbesondere
%Vor%gibt wahr zurück, was verwirrend ist.
Um dieses Problem zu vermeiden, müssen Sie etwas wie
tun %Vor%um elementweise zu vergleichen.
Alternativ können Sie Seq.compareWith
verwenden, wie in Genes Antwort beschrieben. Dies setzt jedoch voraus, dass die Elemente auch einen Vergleichsoperator sowie Gleichheit implementieren, was bei manchen Dingen wie diskriminierten Gewerkschaften, die =
, aber keinen Vergleich implementieren, nicht der Fall sein kann.
Hinzufügen zu Johns Antwort: Sequenzgleichheit kann mit Seq.compareWith
Bibliotheksfunktion bestimmt werden:
Dann wäre die Sequenzgleichheit der Wert des Ausdrucks
%Vor%MSDN für Operators.seq & lt; 'T & gt; Funktion sagt: Erstellt eine Sequenz mit Sequenz Ausdruckssyntax. Wenn Sie sich die Implementierung ansehen , Ich sehe, dass es im Grunde nur eine Identitätsfunktion ist, die eine spezielle Bedeutung für den Compiler hat, nur wenn sie mit der Sequenzausdrucksyntax verwendet wird. Wenn Sie mit einer Liste anrufen, erhalten Sie die gleiche Liste zurück (upcasted auf Seq & lt; _ & gt;).
Zu strukturelle Gleichheit, pro F # spec:
Standardmäßig enthalten Definitionen für Datensatz, Union und Strukturtyp - Strukturtypen genannt - implizit Include Compiler-generierte Deklarationen für strukturelle Gleichheit, Hashing und Vergleich. Diese impliziten Deklarationen bestehen aus den folgenden für strukturelle Gleichheit und Hashing:
%Vor%Die folgenden Deklarationen ermöglichen einen Strukturvergleich:
%Vor%Für Ausnahmetypen werden implizite Deklarationen für strukturelle Gleichheit und Hashes erzeugt, aber Deklarationen für Strukturvergleiche werden nicht generiert. Implizite Deklarationen werden niemals für Interface-, Delegat-, Klassen- oder Enum-Typen generiert. Enum-Typen leiten implizit Unterstützung für Gleichheit, Hashing und Vergleich durch ihre zugrunde liegende Darstellung als Ganzzahlen
Also Listen (im Wesentlichen Gewerkschaften) - unterstützen strukturelle Gleichheit und Sequenzen - nicht. Um Elemente paarweise zu überprüfen, können Sie auch Seq.forall2
verwenden %Vor%Strukturelle Gleichheit wird für Sequenzen nicht unterstützt.
Wenn Sie an ein seq
als .NET IEnumerable<T>
denken, macht das vielleicht mehr Sinn? Hier ist seq [1;2;3] = seq [1;2;3]
ein unglücklicher Zufall. Betrachten Sie ein nicht-reines seq
:
Ergebnis:
%Vor% Verwenden Sie list
anstelle von seq
hier.
Siehe die anderen Antworten.
Tags und Links f#