Первоклассный модуль Ocaml и расширенный вариант - PullRequest
0 голосов
/ 07 мая 2018

Я попытался использовать первоклассный модуль, реализовав этот кусок кода:

module Component =
  struct

    type t_data = ..

    module type S =
      sig
        type t
        val create : t -> t_data
      end

    module Make (C: sig type t end) =
      struct
        type t = C.t
        type t_data += T of C.t
        let create data = T data
      end

  end

let create m data =
  let module M = (val m : Component.S) in M.create data

(*  The type constructor M.t would escape its scope *)

Я бы тоже попробовал эту альтернативу, но я не знаю, как добавить расширенный тип t_data в модуль S:

let create' m data =
  let module M = (val m : Component.S) in M.T data
(* Unbound constructor M.T *)

Я использую пряжки, спасибо!

1 Ответ

0 голосов
/ 07 мая 2018

Вам просто нужны дополнительные аннотации, чтобы убедить типографа:

let create (type t0) (m : (module Component.S with type t = t0)) data =
  let module M = (val m) in M.create data

Что можно сократить на:

let create (type t0) (module M : Component.S with type t = t0) data =
  M.create data

В аннотации (type t) вводится локальный абстрактный тип данных. Вне функции этот тип превращается в переменную универсального типа, поэтому ему присваивается тип:

val create : (module Component.S with type t = 'a) -> 'a -> Component.t_data

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

let inject (type t0) data =
  let module M0 = struct type t = t0 end in
  let module M = Component.Make(M0) in
  M.create data
val make : 'a -> Component.t_data
...