Types Ocaml一级模块和扩展变量

Types Ocaml一级模块和扩展变量,types,module,ocaml,first-class,Types,Module,Ocaml,First Class,我通过实现以下代码尝试使用一流模块: 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_d

我通过实现以下代码尝试使用一流模块:

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 *)
我也会尝试这个替代方案,但我不知道如何在模块S中添加扩展类型t_数据:

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

我正在使用bucklescript,谢谢

您只需要一些额外的注释就可以说服typechecker:

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

您只需要一些额外的注释就可以说服typechecker:

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

还有,你知道M.t会脱离它的范围意味着什么吗?据我所知,typechecker只检查包含等待调用方定义的抽象类型的Component.S(参数m不是流程的一部分)?这或多或少意味着您的函数将返回外部环境没有名称的类型。在这里,
M.t
外部没有名称,因为它隐藏在值
M
中。在这种情况下,它或多或少是一个不完整类型推断的产物:最终的类型通过一个类型变量来代替。大多数人都理解,这是一个需要驯服的巨大野兽!谢谢你,感官上,你知道M.t会脱离它的范围意味着什么吗?据我所知,typechecker只检查包含等待调用方定义的抽象类型的Component.S(参数m不是流程的一部分)?这或多或少意味着您的函数将返回外部环境没有名称的类型。在这里,
M.t
外部没有名称,因为它隐藏在值
M
中。在这种情况下,它或多或少是一个不完整类型推断的产物:最终的类型通过一个类型变量来代替。大多数人都理解,这是一个需要驯服的巨大野兽!谢谢你,老师