10.22 Обобщенные операторы открытого доступа
(Введено в 4.08)
|
Это расширение позволяет открыть любое выражение модуля в структурах и выражениях модулей. Аналогичный механизм также доступен внутри типов модулей, но только для расширенных путей модулей (например, F(X).G(Y)).
Например, модуль может быть ограничен при открытии с
module M = struct let x = 0 let hidden = 1 end open (M:sig val x: int end) let y = hidden Error: Unbound value hidden
Другой вариант — немедленно открыть результат применения функции
let sort (type x) (x:x list) =
let open Set.Make(struct type t = x let compare=compare end) in
elements (of_list x)
val sort : 'x list -> 'x list = Более того, эта конструкция может вводить локальные компоненты внутри структуры,
module M = struct
let x = 0
open! struct
let x = 0
let y = 1
end
let w = x + y
end
module M : sig val x : int val w : int end Одно важное ограничение состоит в том, что типы, введенные с помощью open struct ... end, не могут отображаться в сигнатуре заключительной структуры, если они не определены как равные какому-либо нелокальному типу. Таким образом:
module M = struct open struct type 'a t = 'a option = None | Some of 'a end let x : int t = Some 1 end module M : sig val x : int option end
это нормально, но:
module M = struct
open struct type t = A end
let x = A
end
Error: The type t/567 introduced by this open appears in the signature
File "extensions/generalizedopens.etex", line 3, characters 6-7:
The value x has no valid type if t/567 is hidden нет, потому что x не может получить какой-либо тип, кроме t, который существует только локально. Хотя вышеуказанное было бы нормально, если бы x также был локальным:
module M: sig end = struct open struct type t = A end … open struct let x = A end … end module M : sig end
Внутри сигнатур расширенные открытия ограничиваются расширенными путями модулей,
module type S = sig
module F: sig end -> sig type t end
module X: sig end
open F(X)
val f: t
end
module type S =
sig
module F : sig end -> sig type t end
module X : sig end
val f : F(X).t
end а не
open struct type t = int end
В этих ситуациях вместо этого можно использовать локальные подстановки (см. 10.7.2).
Обратите внимание, что это расширение недоступно внутри определений классов:
class c = let open Set.Make(Int) in ...
© 1995-2022 INRIA.
https://v2.ocaml.org/releases/4.14/htmlman/generalizedopens.html