Spec-Zone.ru › OCaml
☰Язык OCaml
  • Язык OCaml
  • Расширения языка

Глава 12 Расширения языка

26 Кортежи с метками

(Добавлено в OCaml 5.4)

typexpr ::= ...
∣ [label-name:] typexpr { * [label-name:]typexpr }+
expr ::= ...
∣ [~label-name:] expr { , [~label-name:] expr }+
pattern ::= ...
∣ [~label-name:] pattern { , [~label-name:] pattern }+

Начиная с OCaml 5.4, элементам кортежа можно при желании присваивать метки. Эта возможность концептуально противоположна именованным аргументам функций: она позволяет давать понятные имена создаваемым значениям, тогда как именованные аргументы функций позволяют давать понятные имена параметрам.

Вот пример, иллюстрирующий задачу: вычислить два значения по списку и не перепутать их:

let sum_and_product ints =
  let init = ~sum:0, ~product:1 in
  List.fold_left (fun (~sum, ~product) elem ->
    let sum = elem + sum in
    let product = elem * product in
    ~sum, ~product) init ints

val sum_and_product : int list -> sum:int * product:int = 

В этом примере показано использование кортежей с метками в типах и шаблонах. Метки можно опускать, как и у элементов записей или аргументов функций.

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

(sum:int * product:int) -> int -> sum:int * product:int

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

Некоторым элементам кортежа можно присвоить метки, а другим — нет. Это бывает полезно, когда элементы одного типа нужно различать, а остальные — нет. Например:

type min_max_avg = min:int * max:int * float

Изменение порядка и неполные шаблоны

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

Например, можно написать:

let lt = ~x:0, ~y:42
let twice_y = let ~y, .. = lt in y * 2

val lt : x:int * y:int = (~x:0, ~y:42)
val twice_y : int = 84

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

let get_y t =
  let ~y, .. = t in
  y

Error: Could not determine the type of this partial tuple pattern.

Эту проблему можно решить, добавив аннотацию типа к параметру функции.

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

Ограничения

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

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

Для кортежей с метками не поддерживается проекция (извлечение элемента кортежа по метке).

Связь с гибкими записями

Кортежи с метками концептуально похожи на гибкие записи в SML. Основное различие в том, что записи SML канонически упорядочены по именам меток, а кортежи с метками — нет. Например, x:int * y:bool и y:bool * x:int в OCaml — разные типы, соответствующие разному порядку полей в блоке времени выполнения. В SML соответствующие типы записей считаются равными, а поля в блоке времени выполнения всегда упорядочены так, что поле x идёт первым.

« Разрешение неоднозначности литералов массивов с учётом типаВнешние типы »
Copyright © 2026 Institut National de Recherche en Informatique et en Automatique

© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/labeledtuples.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API