Базовые типы и кортежи

Знакомимся с примитивными типами F# и кортежами — простейшим способом сгруппировать значения.

Кортеж (tuple) — упорядоченный набор значений фиксированной длины, возможно разных типов: (1, "a", true) имеет тип int * string * bool.

Примитивные типы

F# использует типы .NET, но с краткими именами F#.

ТипПримерНазначение
int42целое 32-бит
float3.14число с плавающей точкой (double)
booltrueлогическое
char'A'символ
string"текст"строка
unit()«нет значения» (аналог void)

Особое внимание — unit со значением (). Его возвращают функции, выполняемые ради эффекта (например, печати). В F# нет «ничего не возвращающих» функций — они возвращают unit.

Кортежи: группировка без церемоний

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

let point = (3, 4)             // тип: int * int
let person = ("Аня", 25)       // тип: string * int
printfn "%A" point

Вывод:

(3, 4)

Тип кортежа записывается через *: int * int читается как «пара целых».

Распаковка кортежа

Извлечь компоненты можно сопоставлением с образцом прямо в let.

let (name, age) = ("Борис", 30)
printfn "%s, %d лет" name age

Вывод:

Борис, 30 лет

Для пар есть готовые функции fst (первый элемент) и snd (второй).

let pair = (10, 20)
printfn "%d %d" (fst pair) (snd pair)

Вывод:

10 20

Возврат нескольких значений

Кортежи — естественный способ вернуть из функции сразу несколько результатов, без out-параметров как в C#.

let divmod a b = (a / b, a % b)
let (q, r) = divmod 17 5
printfn "частное %d, остаток %d" q r

Вывод:

частное 3, остаток 2

Как работает под капотом

Кортежи F# компилируются в типы System.Tuple/System.ValueTuple платформы .NET, поэтому совместимы с C#. Длина и типы элементов фиксированы на этапе компиляции — кортеж int * string и int * int это разные типы, и компилятор это контролирует. В отличие от записей и классов, у элементов кортежа нет имён, только позиции.

Частые ошибки

  • Использовать кортежи там, где у полей должны быть имена — тогда лучше record (см. далее).
  • Забывать, что fst/snd работают только для пар (двух элементов).
  • Путать unit () с пустым кортежем — это «нет значения», а не данные.

Итоги

  • Базовые типы: int, float, bool, char, string, unit.
  • unit (()) возвращают функции, выполняемые ради эффекта.
  • Кортеж группирует значения; тип записывается через *.
  • Кортежи удобны для возврата нескольких значений и легко распаковываются.
Проверьте себя
1. Какой тип у кортежа (1, "a", true)?
Aint, string, bool
Bint * string * bool
Ctuple<3>
Dobject[]
2. Что представляет тип unit со значением ()?
AЧисло ноль
BПустую строку
CОтсутствие значимого результата (аналог void)
DОшибку
3. Зачем удобны кортежи?
AДля динамической типизации
BЧтобы вернуть несколько значений без объявления класса
CДля замены циклов
DЧтобы отключить вывод типов