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

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

19 Расширенные операторы индексирования

  • 19.1 Обозначение с несколькими индексами

(Добавлено в версии 4.06)

dot-ext ::=
∣ dot-operator-char { operator-char }
dot-operator-char ::= ! ∣ ? ∣ core-operator-char ∣ % ∣ :
expr ::= ...
∣ expr . [module-path .] dot-ext ( ( expr ) ∣ [ expr ] ∣ { expr } ) [ <- expr ]
operator-name ::= ...
∣ . dot-ext (() ∣ [] ∣ {}) [<-]

Это расширение предоставляет синтаксический сахар для получения и изменения элементов индексируемых типов, определённых пользователем. Например, можно определить словари в стиле Python следующим образом:

module Dict = struct
include Hashtbl
let ( .%{} ) tabl index = find tabl index
let ( .%{}<- ) tabl index value = add tabl index value
end
let dict =
  let dict = Dict.create 10 in
  let () =
    dict.Dict.%{"one"} <- 1;
    let open Dict in
    dict.%{"two"} <- 2 in
  dict
# dict.Dict.%{"one"};;

- : int = 1
# let open Dict in dict.%{"two"};;

- : int = 2

19.1 Обозначение с несколькими индексами

expr ::= ...
∣ expr . [module-path .] dot-ext ( expr { ; expr }+ ) [ <- expr ]
∣ expr . [module-path .] dot-ext [ expr { ; expr }+ ] [ <- expr ]
∣ expr . [module-path .] dot-ext { expr { ; expr }+ } [ <- expr ]
operator-name ::= ...
∣ . dot-ext ((;..) ∣ [;..] ∣ {;..}) [<-]

Также поддерживаются несколько индексов — для этого предусмотрен второй вариант операторов индексирования

let (.%[;..]) = Bigarray.Genarray.get
let (.%{;..}) = Bigarray.Genarray.get
let (.%(;..)) = Bigarray.Genarray.get

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

let sum x y = x.%[1;2;3] + y.%[1;2]
(* is equivalent to *)
let sum x y = (.%[;..]) x [|1;2;3|] + (.%[;..]) y [|1;2|]

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

module A = Bigarray.Genarray
let (.%{;..}) = A.get
let (.%{;..}<- ) = A.set
let (.%{ }) a k = A.get a [|k|]
let (.%{ }<-) a k x = A.set a [|k|] x
let syntax_compare vec mat t3 t4 =
          vec.%{0} = A.get vec [|0|]
   &&   mat.%{0;0} = A.get mat [|0;0|]
   &&   t3.%{0;0;0} = A.get t3 [|0;0;0|]
   && t4.%{0;0;0;0} = t4.{0,0,0,0}

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

  let pair vec mat = vec.%{0}, mat.%{0;0}

эквивалентно

  let pair vec mat = (.%{ }) vec 0, (.%{;..}) mat [|0;0|]

Обратите внимание: в случае vec вызывается оператор для одного индекса (.%{}), а не вариант для нескольких индексов (.{;..}). Поэтому большинству пользователей операторов для нескольких индексов, вероятно, потребуется совместно определить вариант для одного индекса

let (.%{;..}) = A.get
let (.%{ }) a k = A.get a [|k|]

чтобы единообразно обрабатывать оба случая.

« Комментарии к документацииТипы с пустыми вариантами »
Copyright © 2026 Institut National de Recherche en Informatique et en Automatique

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

Spec-Zone.ru

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