如何在OCaml中实现mixin
如何在OCaml模块系统中实现 我实现的最接近的方法是使用以下方法,我在如何在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 =
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非常有用,谢谢!