F # Sequenzvergleich

7

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 werden

Bearbeiten: 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.

    
Wei Ma 14.06.2013, 04:54
quelle

5 Antworten

10

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.

    
John Palmer 14.06.2013, 05:10
quelle
10

Hinzufügen zu Johns Antwort: Sequenzgleichheit kann mit Seq.compareWith Bibliotheksfunktion bestimmt werden:

%Vor%

Dann wäre die Sequenzgleichheit der Wert des Ausdrucks

%Vor%     
Gene Belitski 14.06.2013 05:34
quelle
3

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%     
desco 15.06.2013 05:18
quelle
1

Der Grund:

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 :

%Vor%

Ergebnis:

%Vor%

Die offensichtliche Antwort:

Verwenden Sie list anstelle von seq hier.

%Vor%

Die Details:

Siehe die anderen Antworten.

    
johv 05.12.2013 15:45
quelle
1

Für jeden, der diese Antwort findet, der einfach zwei Sequenzen vergleichen möchte, gibt es eine Alternative zu Seq.compareWith:

Es gibt eine .NET-Methode Enumerable.SequenceEqual . Ich benutze dies die ganze Zeit beim Testen.

Beispielverwendung:

%Vor%     
Richiban 09.02.2017 13:21
quelle

Tags und Links