Кортежи

Кортеж представляет собой группирование неназванных, но упорядоченных значений, возможно, различных типов. Кортежи могут быть ссылочными типами или структурами.

Синтаксис

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

Замечания

Каждый элемент в предыдущем синтаксисе может быть любым допустимым выражением F#.

Примеры

Примеры кортежей включают пары, тройные и т. д. одинаковых или разных типов. Некоторые примеры показаны в следующем коде.

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

Получение отдельных значений

Вы можете использовать сопоставление шаблонов для доступа и назначения имен для элементов кортежа, как показано в следующем коде.

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

Вы также можете деконструировать кортеж с помощью сопоставления шаблонов match за пределами выражения с помощью let привязки:

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

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

Кроме того, можно указать соответствие кортежам в качестве входных данных для функций:

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

Если вам нужен только один элемент кортежа, можно использовать дикий символ карта (подчеркивание), чтобы избежать создания нового имени для значения, которое не требуется.

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

Копирование элементов из ссылочного кортежа в кортеж структуры также является простым:

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

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

Функции fst и snd (только ссылочные кортежи) возвращают первые и второй элементы кортежа соответственно.

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

Встроенная функция не возвращает третий элемент тройного, но его можно легко написать следующим образом.

let third (_, _, c) = c

Как правило, лучше использовать сопоставление шаблонов для доступа к отдельным элементам кортежа.

Использование кортежей

Кортежи предоставляют удобный способ возврата нескольких значений из функции, как показано в следующем примере. В этом примере выполняется целочисленное деление и возвращает округленный результат операции в качестве первого члена пары кортежей и остаток в качестве второго члена пары.

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

Кортежи также можно использовать в качестве аргументов функций, если вы хотите избежать неявного карриинга аргументов функций, подразумеваемых обычным синтаксисом функции.

let sumNoCurry (a, b) = a + b

Обычный синтаксис для определения функции позволяет определить функцию, которая является частичным применением первого аргумента функции let sum a b = a + b , как показано в следующем коде.

let sum a b = a + b

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

Использование кортежа в качестве параметра отключает карриирование. Дополнительные сведения см. в разделе "Частичное применение аргументов" в функциях.

Имена типов кортежей

При написании имени типа, который является кортежем, вы используете * символ для разделения элементов. Для кортежа, состоящего из intтипа , а floatтакже string(10, 10.0, "ten")типа, будет написан следующим образом.

int * float * string

Обратите внимание, что внешние скобки являются обязательными при создании псевдонима типа для типа кортежа структуры.

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

Взаимодействие с кортежами C#

Кортежи в C# являются структурами и эквивалентны кортежам структур в F#. Если необходимо взаимодействовать с C#, необходимо использовать кортежи структур.

Это легко сделать. Например, представьте, что необходимо передать кортеж в класс C#, а затем использовать его результат, который также является кортежем:

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

В коде F# можно передать кортеж структуры в качестве параметра и использовать результат в качестве кортежа структуры.

open TupleInterop

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

Преобразование между кортежами ссылок и кортежами структуры

Так как кортежи ссылок и кортежи структуры имеют совершенно другое базовое представление, они неявно преобразуются. То есть код, например следующий, не будет компилироваться:

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

Необходимо сопоставить шаблон на одном кортеже и создать другой с составными частями. Например:

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

Скомпилированный вид ссылочных кортежей

В этом разделе объясняется форма кортежей при компиляции. Сведения здесь не нужны для чтения, если вы не нацелены на платформа .NET Framework 3.5 или более поздней версии.

Кортежи компилируются в объекты одного из нескольких универсальных типов, все именованные System.Tuple, которые перегружены на arity или число параметров типа. Типы кортежей отображаются в этой форме при просмотре их с другого языка, например C# или Visual Basic, или при использовании средства, которое не знает о конструкциях F#. Tuple Типы были введены в платформа .NET Framework 4. Если вы используете более раннюю версию платформа .NET Framework, компилятор использует версии System.Tuple из версии 2.0 основной библиотеки F#. Типы в этой библиотеке используются только для приложений, предназначенных для версий 2.0, 3.0 и 3.5 платформа .NET Framework. Перенаправление типов используется для обеспечения совместимости двоичных файлов между компонентами платформа .NET Framework 2.0 и платформа .NET Framework 4 F#.

Скомпилированный вид кортежей структур

Кортежи структуры (например, struct (x, y)) существенно отличаются от ссылочных кортежей. Они компилируются в ValueTuple тип, перегружены arity или число параметров типа. Они эквивалентны кортежам C# и кортежам Visual Basic, а также взаимодействуют двунаправленно.

См. также