Tuples

Un tuple est un regroupement de valeurs sans nom mais triées, éventuellement de types distincts. Les tuples peuvent être des types référence ou des structs.

Syntaxe

(element, ... , element)
struct(element, ... ,element )

Notes

Chaque élément de la syntaxe précédente peut être une expression F# valide.

Exemples

Parmi les exemples de tuples, citons les couples, les triplets, etc., de types identiques ou différents. Certains exemples sont illustrés dans le code suivant.

(1, 2)

// Triple of strings.
("one", "two", "three")

// Tuple of generic types.
(a, b)

// Tuple that has mixed types.
("one", 1, 2.0)

// Tuple of integer expressions.
(a + 1, b + 1)

// Struct Tuple of floats
struct (1.025f, 1.5f)

Obtention de valeurs individuelles

Vous pouvez utiliser des critères spéciaux pour accéder aux éléments de tuple, et leur affecter des noms, comme le montre le code suivant.

let print tuple1 =
   match tuple1 with
    | (a, b) -> printfn "Pair %A %A" a b

Vous pouvez également déconstruire un tuple via des critères spéciaux en dehors d’une expression match via une liaison let :

let (a, b) = (1, 2)

// Or as a struct
let struct (c, d) = struct (1, 2)

Vous pouvez également rechercher à l’aide de critères spéciaux des tuples en tant qu’entrées de fonctions :

let getDistance ((x1,y1): float*float) ((x2,y2): float*float) =
    // Note the ability to work on individual elements
    (x1*x2 - y1*y2) 
    |> abs 
    |> sqrt

Si vous n’avez besoin que d’un seul élément du tuple, vous pouvez utiliser le caractère générique (trait de soulignement) afin d’éviter de créer un nom pour une valeur dont vous n’avez pas besoin.

let (a, _) = (1, 2)

La copie d’éléments d’un tuple de référence dans un tuple de struct est également simple :

// Create a reference tuple
let (a, b) = (1, 2)

// Construct a struct tuple from it
let struct (c, d) = struct (a, b)

Les fonctions fst et snd (tuples de référence uniquement) retournent respectivement le premier et le deuxième élément d’un tuple.

let c = fst (1, 2)
let d = snd (1, 2)

Il n’existe aucune fonction intégrée qui retourne le troisième élément d’un triplet, mais vous pouvez facilement en écrire une, comme indiqué ci-après.

let third (_, _, c) = c

En règle générale, il est préférable d’utiliser des critères spéciaux pour accéder aux éléments de tuple individuels.

Utilisation de tuples

Les tuples offrent un moyen pratique de retourner plusieurs valeurs à partir d’une fonction, comme le montre l’exemple suivant. Cet exemple effectue une division d’entiers, puis retourne le résultat arrondi de l’opération en tant que premier membre d’une paire de tuples, et le reste en tant que deuxième membre de la paire.

let divRem a b =
   let x = a / b
   let y = a % b
   (x, y)

Les tuples peuvent également être utilisés en tant qu’arguments de fonction quand vous souhaitez éviter la curryfication implicite des arguments de fonction, qui est indiquée par la syntaxe de fonction habituelle.

let sumNoCurry (a, b) = a + b

La syntaxe habituelle pour définir la fonction let sum a b = a + b vous permet de définir une fonction qui est l’application partielle du premier argument de la fonction, comme le montre le code suivant.

let sum a b = a + b

let addTen = sum 10
let result = addTen 95
// Result is 105.

L’utilisation d’un tuple en tant que paramètre désactive la curryfication. Pour plus d’informations, consultez "Application partielle d’arguments" dans Fonctions.

Noms des types tuples

Quand vous écrivez le nom d’un type qui est un tuple, vous utilisez le symbole * pour séparer les éléments. Pour un tuple composé de int, de float et de string, par exemple (10, 10.0, "ten"), le type est écrit de la façon suivante.

int * float * string

Notez que les parenthèses externes sont obligatoires au moment de la création d’un alias de type pour un type tuple de struct.

type TupleAlias = string * float
type StructTupleAlias = (struct (string * float))

Interopérabilité avec les tuples C#

Les tuples en C# sont des structs et sont équivalents aux tuples de struct en F#. Si vous avez besoin d’interopérabilité en C#, vous devez utiliser des tuples de struct.

C’est très simple. Par exemple, imaginons que vous deviez passer un tuple à une classe C#, puis consommer son résultat, qui est également un tuple :

namespace CSharpTupleInterop
{
    public static class Example
    {
        public static (int, int) AddOneToXAndY((int x, int y) a) =>
            (a.x + 1, a.y + 1);
    }
}

Dans votre code F#, vous pouvez ensuite passer un tuple de struct en tant que paramètre, et consommer le résultat sous forme de tuple de struct.

open TupleInterop

let struct (newX, newY) = Example.AddOneToXAndY(struct (1, 2))
// newX is now 2, and newY is now 3

Conversion entre tuples de référence et tuples de struct

Dans la mesure où les tuples de référence et les tuples de struct ont une représentation sous-jacente complètement différente, ils ne sont pas implicitement convertibles. En d’autres termes, la compilation du code suivant ne peut pas réussir :

// Will not compile!
let (a, b) = struct (1, 2)

// Will not compile!
let struct (c, d) = (1, 2)

// Won't compile!
let f(t: struct(int*int)): int*int = t

Vous devez utiliser des critères spéciaux pour rechercher un tuple, et construire l’autre tuple avec les parties constituantes. Par exemple :

// Pattern match on the result.
let (a, b) = (1, 2)

// Construct a new tuple from the parts you pattern matched on.
let struct (c, d) = struct (a, b)

Forme compilée de tuples de référence

Cette section décrit la forme des tuples quand ils sont compilés. Il n’est pas nécessaire de lire les informations fournies ici, sauf si vous ciblez .NET Framework 3.5 ou une version antérieure.

Les tuples sont compilés en objets ayant l’un des types génériques disponibles, tous nommés System.Tuple, qui sont surchargés en fonction de l’arité ou du nombre de paramètres de type. Les types de tuple s’affichent sous cette forme quand vous les visualisez à partir d’un autre langage, par exemple C# ou Visual Basic, ou quand vous utilisez un outil qui ne prend pas en charge les constructions F#. Les types Tuple ont été introduits dans .NET Framework 4. Si vous ciblez une version antérieure du .NET Framework, le compilateur utilise les versions de System.Tuple à partir de la version 2.0 de la bibliothèque principale F#. Les types de cette bibliothèque sont utilisés uniquement pour les applications qui ciblent les versions 2.0, 3.0 et 3.5 du .NET Framework. Le transfert de type est utilisé pour garantir la compatibilité binaire entre les composants F# de .NET Framework 2.0 et .NET Framework 4.

Forme compilée des tuples de struct

Les tuples de struct (par exemple struct (x, y)) sont fondamentalement différents des tuples de référence. Ils sont compilés dans le type ValueTuple, surchargé en fonction de l’arité ou du nombre de paramètres de type. Ils sont équivalents aux tuples C# et aux tuples Visual Basic, et interagissent de manière bidirectionnelle.

Voir aussi