F # 6: Tuples

Notre voyage vers F # continue donc. L'article suivant se concentrera sur les types F # qui peuvent ou non avoir des équivalents .NET standard. Ce message concerne les tuples.

Que sont les tuples


Un tuple est un groupe de valeurs non nommées mais ordonnées, éventuellement de types différents.

Création de tuples


Les tuples sont très faciles à créer, nous faisons juste quelque chose comme celui ci-dessous. Remarquez comment j'ai créé un package mixte de tuples, dont certains sont des nombres et d'autres des chaînes, et nous pouvons également mélanger et faire correspondre les deux types et le nombre de valeurs.

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

Tuples universels


Les fonctions qui acceptent les tuples peuvent également accepter sans problème des tuples universels. Un système d'inférence tel que F # se fera un plaisir de gérer l'inférence des types corrects pour un tuple. Voici un exemple.

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

Et voici les résultats de l'exécution ci-dessus, où vous pouvez voir que la fonction someFunction a accepté et a fonctionné sans problème avec divers tuples typés.

image

Signatures de tuple


Jusqu'à présent, nous n'avons pas du tout abordé la compréhension des signatures F #, en fait, c'est un sujet auquel j'ai également décidé de consacrer un blog entier, car je pense que c'est assez compliqué. Cependant, nous sommes situés là où nous sommes, c'est-à-dire ici et maintenant, et nous étudions les tuples, alors maintenant je voulais juste montrer à quoi ressemblerait la signature du tuple.

Supposons que j'ai déclaré les tuples suivants dans la fenêtre FSI:
 let a = (1,2) let b = (1,"codfather") let c = (1,"c", 12.5) 

Et puis je les ai examinés dans la fenêtre FSI; nous verrons quelque chose comme ceci:
 val a : int * int = (1, 2) val b : int * string = (1, "codfather") val c : int * string * float = (1, "c", 12.5) 

C'est intéressant, nous pouvons voir quelques choses ici, à savoir:
  • Les parenthèses ne font pas partie d'une signature de type
  • Le système de type F # peut correctement déduire un type basé sur les valeurs contenues dans le tuple lui-même.
  • La virgule est remplacée par "*"

Ainsi, le tuple cristallin ressemble à ceci:
 let a = (1,2) 

Aura la signature suivante:
 int * int 


Répartition du tuple


Nous avons donc vu comment créer des tuples, mais qu'en est-il de les casser ou de les déconstruire en valeurs distinctes. Est-ce possible? Oui bien sûr. Comme précédemment, commençons par quelques exemples:
 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 

Les résultats sont imprimés dans une fenêtre de console standard, comme suit:
image

Utilisation de Let


Mais comment avons-nous obtenu les pièces individuelles? Eh bien, tout ce dont vous avez besoin est le code ci-dessus, mais regardons un exemple. Supposons que nous ayons un tuple comme celui-ci:
 (1,2) 

Et je voulais que les valeurs des deux "valeurs" du tuple soient liées à de nouvelles valeurs individuelles, nous pourrions simplement faire ceci:
 let (a,b) = (1,2) 

Nous pouvons également sélectionner uniquement les valeurs dont nous avons vraiment besoin, ce qui se fait à l'aide d'un caractère générique pour les parties indésirables. Ce qui garantit l'absence de reliure de valeur inutile. Voici un exemple:
 let (_,z) = (1,2) 


Utilisation des fonctions de tuple intégrées


Il existe également une prise en charge intégrée pour obtenir les première et deuxième valeurs d'un tuple. Que peut-on faire en utilisant les fonctions " fst " et " snd ". Il n'y a pas de support pour autre chose que le 2ème élément (ce sont probablement les cas les plus courants). « Fst » et « snd » peuvent être utilisés comme suit:
 let first = fst (1, 2) let second = snd (1, 2) 

Maintenant, je veux attirer votre attention sur un cas particulier où nous pouvons avoir un décalage avec le nombre de valeurs que nous essayons d'exploser en valeurs individuelles. Donc, ce sera quelque chose comme un exemple ici:
 let (a ,b) = (1,"cat", 'c') 

Vous pouvez voir que le tuple lui-même contient en fait 3 valeurs, mais la liaison Let n'a que 2 valeurs, donc le compilateur nous en avertit, comme vous pouvez le voir dans la capture d'écran ci-dessous:
image

Création de nouveaux tuples


Vous voudrez peut-être créer de nouveaux tuples à partir de tuples existants, c'est assez simple, voici un exemple:
 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 

image

Comparaison de tuples


Les tuples ne sont considérés comme égaux que si

  • Ils ont le même nombre de valeurs.
  • TOUTES les valeurs sont considérées comme égales (évidemment, il peut s'agir de méthodes Equals personnalisées ou d'implémentations IEquatable personnalisées, etc.)

Regardons un exemple simple.

 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')) 

image

En fait, si vos tuples ont des longueurs différentes (le nombre d'éléments) et que vous essayez de les comparer en utilisant l'opérateur d'égalité "=", vous obtiendrez un avertissement:
image

Tuple matching patterns


Nous n'avons pas encore traité de modèles de correspondance, mais plus tard, nous verrons un article entier sur ce sujet. En attendant, sachez simplement que c'est une façon de faire correspondre à nouveau les paramètres d'entrée. Vous pouvez le faire pour les tuples, ce qui se fait comme suit:
 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) 

image

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


All Articles