F # 6: Tupel

Also geht unsere Reise nach F # weiter. Der folgende Artikel konzentriert sich auf F # -Typen, die möglicherweise Standard-.NET-Entsprechungen haben oder nicht. In diesem Beitrag geht es um Tupel.

Was sind Tupel?


Ein Tupel ist eine Gruppe unbenannter, aber geordneter Werte, möglicherweise unterschiedlicher Typen.

Tupel erstellen


Tupel sind sehr einfach zu erstellen. Wir machen einfach so etwas wie das unten gezeigte. Beachten Sie, wie ich ein gemischtes Paket von Tupeln erstellt habe, von denen einige Zahlen und andere Zeichenfolgen sind. Außerdem können wir sowohl Typen als auch Anzahl von Werten mischen und abgleichen.

let a = (1,2) let b = (1,"cat") let c = (1,"cat") let d = (1,"cat", 'c') 

Universelle Tupel


Funktionen, die Tupel akzeptieren, können auch universelle Tupel problemlos akzeptieren. Ein Inferenzsystem wie F # verarbeitet gerne die Inferenz der richtigen Typen für ein Tupel. Hier ist ein Beispiel.

 let someFunction tup = let (x,y) = tup printfn "x is %A and y is %A" xy do someFunction ("cat","dog") do someFunction (11,12) 

Und hier sind die Ergebnisse der obigen Ausführung, bei denen Sie sehen können, dass die Funktion someFunction problemlos verschiedene typisierte Tupel akzeptiert und mit diesen funktioniert hat.

Bild

Tupel-Signaturen


Bisher haben wir das Verständnis von F # -Signaturen überhaupt nicht angesprochen. Tatsächlich ist dies ein Thema, dem ich mich auch für einen ganzen Blog-Beitrag entschieden habe, da ich glaube, dass es ziemlich kompliziert ist. Wir befinden uns jedoch dort, wo wir sind, dh hier und jetzt, und wir studieren Tupel. Deshalb wollte ich jetzt nur zeigen, wie die Signatur des Tupels aussehen würde.

Angenommen, ich habe die folgenden Tupel im FSI-Fenster deklariert:
 let a = (1,2) let b = (1,"codfather") let c = (1,"c", 12.5) 

Und dann habe ich sie im FSI-Fenster untersucht. wir werden so etwas sehen:
 val a : int * int = (1, 2) val b : int * string = (1, "codfather") val c : int * string * float = (1, "c", 12.5) 

Das ist interessant, wir können hier ein paar Dinge sehen, nämlich:
  • Klammern sind nicht Teil einer Typensignatur
  • Das F # -Typsystem kann einen Typ basierend auf den im Tupel selbst enthaltenen Werten korrekt ableiten.
  • Das Komma wird durch "*" ersetzt.

Das kristallklare Tupel sieht also so aus:
 let a = (1,2) 

Wird die folgende Unterschrift haben:
 int * int 


Tupel-Aufschlüsselung


Wir haben also gesehen, wie wir Tupel erstellen können, aber wie wäre es, sie wieder in separate Werte zu zerlegen oder zu dekonstruieren. Das ist möglich? Ja natürlich. Beginnen wir nach wie vor mit einigen Beispielen:
 let (a,b) = (1,2) printfn "(a,b) = (1,2), so value of 'a' should be 1, and it is =%i,\r\n 'b' should be 2, and it is =%i" ab //   ,  ,     ,   //     let (_,z) = (1,2) printfn "grabbing last value from (1,2) which is = %i" z let (a,b :string) = (1,"cat") printfn "grabbing (1,\"cat\") which has values = %i %s" ab let (a :int,b :string) = (1,"cat") printfn "grabbing (1,\"cat\") which has values = %i %s" ab let (a ,b, c) = (1,"cat", 'c') printfn "grabbing (1,\"cat\",'c') which has values = %i %s %c" abc let first = fst (1, 2) printfn "grabbing fst from (1,2) which has values = %i" first let second = snd (1, 2) printfn "grabbing 2nd from (1,2) which has values = %i" second 

Die Ergebnisse werden wie folgt in einem Standardkonsolenfenster gedruckt:
Bild

Mit Let


Aber wie haben wir die einzelnen Teile bekommen? Alles, was Sie brauchen, ist der obige Code, aber schauen wir uns ein Beispiel an. Angenommen, wir hatten ein Tupel wie dieses:
 (1,2) 

Und ich wollte, dass die Werte beider "Werte" des Tupels mit einigen neuen Einzelwerten verknüpft werden. Wir könnten dies einfach tun:
 let (a,b) = (1,2) 

Wir können auch nur die Werte auswählen, die wir wirklich benötigen. Dies erfolgt mithilfe eines Platzhalters für unerwünschte Teile. Dies garantiert das Fehlen einer unnötigen Wertebindung. Hier ist ein Beispiel:
 let (_,z) = (1,2) 


Verwenden der integrierten Tupelfunktionen


Es gibt auch eine integrierte Unterstützung zum Abrufen des ersten und zweiten Werts von einem Tupel. Was kann mit den Funktionen " fst " und " snd " getan werden ? Es gibt keine Unterstützung für etwas anderes als das 2. Element (dies sind wahrscheinlich die häufigsten Fälle). " Fst " und " snd " können wie folgt verwendet werden:
 let first = fst (1, 2) let second = snd (1, 2) 

Jetzt möchte ich Ihre Aufmerksamkeit auf einen Sonderfall lenken, in dem die Anzahl der Werte, die wir in einzelne Werte auflösen möchten, möglicherweise nicht übereinstimmt. Das wird hier also so etwas wie ein Beispiel sein:
 let (a ,b) = (1,"cat", 'c') 

Sie können sehen, dass das Tupel selbst tatsächlich 3 Werte enthält, die Let-Bindung jedoch nur 2 Werte. Der Compiler warnt uns daher davor, wie Sie im folgenden Screenshot sehen können:
Bild

Neue Tupel erstellen


Möglicherweise möchten Sie neue Tupel aus vorhandenen Tupeln erstellen. Dies ist ganz einfach. Hier ein Beispiel:
 let oldOne = (1,2) let (x,y) = oldOne let newOne = (x+1,y+1) printfn "original = %A, and we did this (x+1,y+1)\r\n to obtain newOne = %A" oldOne newOne 

Bild

Vergleich von Tupeln


Tupel gelten nur dann als gleich, wenn

  • Sie haben die gleiche Anzahl von Werten.
  • ALLE Werte werden als gleich angesehen (dies können natürlich benutzerdefinierte Equals-Methoden oder benutzerdefinierte IEquatable-Implementierungen und dergleichen sein).

Schauen wir uns ein einfaches Beispiel an.

 printfn "(1,2) = (3,4) =% b" ((1,2) = (3,4)) printfn "(1,2) = (1,2) =% b" ((1,2) = (1,2)) printfn "('a', 'b') = ('a', 'b') =% b" (('a', 'b') = ('a', 'b')) printfn "('a', 'b') = ('a', 'c') =% b" (('a', 'b') = ('a', 'c')) 

Bild

Wenn Ihre Tupel unterschiedliche Längen haben (die Anzahl der Elemente) und Sie versuchen, sie mit dem Gleichheitsoperator "=" zu vergleichen, erhalten Sie eine Warnung:
Bild

Tupel passende Muster


Wir haben uns noch nicht mit passenden Mustern befasst, aber später werden wir einen ganzen Beitrag zu diesem Thema sehen. In der Zwischenzeit sollten Sie nur wissen, dass dies eine Möglichkeit ist, die Eingabeparameter wieder anzupassen. Sie können dies für Tupel wie folgt tun:
 let someFunction tup = match tup with | 1,2 -> printfn "you passed (1,2)" | _,_ -> printfn "you passed some other tuple" do someFunction (11,12) do someFunction (4,5) do someFunction (1,2) do someFunction (13,23) 

Bild

Source: https://habr.com/ru/post/de470271/


All Articles