Tuplas

Una tupla es una agrupación de valores sin nombre pero ordenados, posiblemente de tipos diferentes. Las tuplas pueden ser tipos de referencia o estructuras.

Sintaxis

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

Comentarios

Cada elemento de la sintaxis anterior puede ser cualquier expresión de F# válida.

Ejemplos

Algunos ejemplos de tuplas incluyen pares, triples, etc., de los mismos tipos o diferentes. Algunos ejemplos quedan reflejados en el código siguiente.

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

Obtener valores individuales

Puedes usar la coincidencia de patrones para acceder a los elementos de tupla y asignar nombres, como se muestra en el código siguiente.

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

También puedes deconstruir una tupla mediante la coincidencia de patrones fuera de una match expresión mediante let el enlace:

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

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

O bien, puedes establecer coincidencias en tuplas como entradas para las funciones:

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 solo necesitas un elemento de la tupla, se puede usar el carácter comodín (el carácter de subrayado) para evitar crear un nuevo nombre para un valor que no necesite.

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

La copia de elementos de una tupla de referencia en una tupla de estructura también es sencilla:

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

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

Las funciones fst y snd (solo tuplas de referencia) devuelven los elementos primero y segundo de una tupla, respectivamente.

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

No hay ninguna función integrada que devuelva el tercer elemento de un triple, pero puede escribir fácilmente una como se indica a continuación.

let third (_, _, c) = c

Por lo general, es mejor usar la coincidencia de patrones para acceder a elementos de tupla individuales.

Uso de tuplas

Las tuplas proporcionan una manera cómoda de devolver varios valores de una función, como se muestra en el ejemplo siguiente. En este ejemplo se realiza la división de enteros y se devuelve el resultado redondeado de la operación como primer miembro de un par de tupla y el resto como segundo miembro del par.

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

Las tuplas también se pueden usar como argumentos de función cuando se desea evitar la conversión implícita de argumentos de función que está implícito en la sintaxis de función habitual.

let sumNoCurry (a, b) = a + b

La sintaxis habitual para definir la función let sum a b = a + b permite definir una función que es la aplicación parcial del primer argumento de la función, como se muestra en el código siguiente.

let sum a b = a + b

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

El uso de una tupla como parámetro deshabilita el currying. Para obtener más información, consulta «Aplicación parcial de argumentos» en Funciones.

Nombres de tipos de tupla

Al escribir el nombre de un tipo que es una tupla, se usa el símbolo * para separar los elementos. Para una tupla que consta de int, y float, stringcomo (10, 10.0, "ten"), el tipo se escribiría de la siguiente manera.

int * float * string

Ten en cuenta que los paréntesis externos son obligatorios al crear un alias de tipo para un tipo de tupla de estructura.

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

Interoperación con Tuplas C#

Las tuplas de C# son estructuras y son equivalentes a tuplas de estructura en F#. Si necesitas interoperar con C#, debes usar tuplas de estructura.

Es fácil de hacer. Por ejemplo, imagina que tienea que pasar una tupla a una clase de C# y, a continuación, consumir su resultado, que también es una tupla:

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

En el código de F#, puedes pasar una tupla de estructura como parámetro y consumir el resultado como una tupla de estructura.

open TupleInterop

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

Conversión entre tuplas de referencia y tuplas de estructura

Dado que las tuplas de referencia y las tuplas de estructura tienen una representación subyacente completamente diferente, no se pueden convertir implícitamente. Es decir, el código como el siguiente no se compilará:

// 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

Debes establecer coincidencias de patrones en una tupla y construir la otra con las partes constituyentes. Por ejemplo:

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

Forma compilada de tuplas de referencia

En esta sección se explica la forma de tuplas cuando se compilan. La información aquí no es necesaria para leer a menos que tenga como destino .NET Framework 3.5 o inferior.

Las tuplas se compilan en objetos de uno de varios tipos genéricos, todos denominados System.Tuple, que se sobrecargan en la aridad o en el número de parámetros de tipo. Los tipos de tupla aparecen en este formulario cuando se ven desde otro lenguaje, como C# o Visual Basic, o cuando se usa una herramienta que no es consciente de las construcciones de F#. Los Tuple tipos se introdujeron en .NET Framework 4. Si tienes como destino una versión anterior de .NET Framework, el compilador usa versiones de System.Tuple de la versión 2.0 de la biblioteca principal de F#. Los tipos de esta biblioteca solo se usan para las aplicaciones destinadas a las versiones 2.0, 3.0 y 3.5 de .NET Framework. El reenvío de tipos se usa para garantizar la compatibilidad binaria entre los componentes de .NET Framework 2.0 y .NET Framework 4 F#.

Forma compilada de tuplas de estructura

Las tuplas de estructura (por ejemplo, struct (x, y)), son fundamentalmente diferentes de las tuplas de referencia. Se compilan en el ValueTuple tipo, sobrecargado por aridad o el número de parámetros de tipo. Son equivalentes a tuplas de C# 7.0 y tuplas de Visual Basic, e interoperan bidireccionalmente.

Vea también