如何在OCaml中实现mixin

如何在OCaml中实现mixin,ocaml,mixins,Ocaml,Mixins,如何在OCaml模块系统中实现 我实现的最接近的方法是使用以下方法,我在MixinFormat上说明了这一方法,它在能够格式化的mixin上添加了常用的输出函数打印、输出和到字符串 假设我们实现了一个具有以下签名的模块MixinFormat: module MixinFormat : sig (** Formatable mixin. *) (** Input signature of the functor [MixinFormat.Make]. *) module type Basis =

如何在OCaml模块系统中实现

我实现的最接近的方法是使用以下方法,我在
MixinFormat
上说明了这一方法,它在能够
格式化
的mixin上添加了常用的输出函数
打印
输出
到字符串

假设我们实现了一个具有以下签名的模块
MixinFormat

module MixinFormat :
sig
(** Formatable mixin. *)

(** Input signature of the functor [MixinFormat.Make]. *)
module type Basis =
sig

  type t
  (** The type of formatted elements. *)

  val format : Format.formatter -> t -> unit
  (** [format fft a] pretty prints [a] on [fft]. *)

end

(** Output signature of the functor [MixinFormat.Make]. *)
module type Methods =
sig
  type t

  val to_string : t -> string
  (** Convert to string. *)

  val output : out_channel -> t -> unit
  (** Output on the given output channel. *)

  val print : t -> unit
  (** Output on the standard output channel. *)

end

(** Functor implementing output mixins based on a format definition. *)
module Make(B:Basis): Methods
  with type t := B.t

(** Signature of formatable mixins. *)
module type S =
sig
  type t
  include Basis with type t := t
  include Methods with type t := t
end
end
现在,我们可以使用它向模块添加通用输出函数,该模块能够
格式化
,如下所示:

module Date =
struct
   module Prototype =
   struct
      type t = int * int * int
      let format ppt (y,m,d) =
        Format.fprintf ppt "%04d-%02d-%02d" y m d
   end
   include Prototype
   include MixinFormat.Make(Prototype)
end
这很好地工作,但方便的是不容易实现:如果第二个mxin希望通过
MixinFormat.Make
将函数添加到
Prototype
中,那么我们需要将
Prototype
MixinFormat.Make(Prototype)
打包到
Prototype2
中,这有点笨拙,并且阻碍了可读性


是否有替代性的mixin实现,可以避免在迭代使用mixin时引入
原型2

首先,为了避免类型
t
的多个定义,您的函子可能应该定义为:

module Make(B:Basis): Methods with type t := B.t
为了避免创建内部模块,可以使用如下递归模块:

module rec Date : sig
  type t = int * int * int
  include Basis with type t := t
  include Methods with type t := t
end = struct
  type t = int * int * int

  let format ppt (y,m,d) =
    Format.fprintf ppt "%04d-%02d-%02d" y m d

  include Make(Date)
end
然而,值得注意的是,递归模块可能有点棘手。例如,如果模块中的任何值(例如,
格式
)不是函数,则此定义将不起作用


还值得注意的是,OCaml的对象系统对混合有极好的支持。例如,请参阅。

我没有想到使用递归模块来实现这一点,但创建内部模块对我来说似乎是一个较小的问题!:)参考真实世界的OCaml非常有用,谢谢!