Module OCaml使用在函子外部定义的签名来限制生成模块的可见性
我正试图编写一个函子,它接受一对有序的事物,并生成另一个有序的事物(按照字典定义的顺序) 但是,我希望得到的“有序类型”是抽象的,而不是OCaml元组 使用内联/匿名签名很容易做到这一点Module OCaml使用在函子外部定义的签名来限制生成模块的可见性,module,ocaml,encapsulation,functor,Module,Ocaml,Encapsulation,Functor,我正试图编写一个函子,它接受一对有序的事物,并生成另一个有序的事物(按照字典定义的顺序) 但是,我希望得到的“有序类型”是抽象的,而不是OCaml元组 使用内联/匿名签名很容易做到这一点 (* orderedPairSetInlineSig.ml *) module type ORDERED_TYPE = sig type t val compare : t -> t -> int end module MakeOrderedPairSet (X : ORDERED_TY
(* orderedPairSetInlineSig.ml *)
module type ORDERED_TYPE = sig
type t
val compare : t -> t -> int
end
module MakeOrderedPairSet (X : ORDERED_TYPE) :
sig
type t
val get_fst : t -> X.t
val get_snd : t -> X.t
val make : X.t -> X.t -> t
val compare : t -> t -> int
end = struct
type t = X.t * X.t
let combine_comparisons fst snd =
if fst = 0 then snd else fst
let compare (x, y) (a, b) =
let cmp = X.compare x a in
let cmp' = X.compare y b in
combine_comparisons cmp cmp'
let get_fst ((x, y) : t) = x
let get_snd ((x, y) : t) = y
let make x y = (x, y)
end
我想给我的匿名签名起一个类似于ORDERED\u PAIR\u SET\u TYPE
的名字,并将其移到MakeOrderedPairSet
的定义之外,就像这样(警告:语法无效):
在签名中,el
是一个抽象类型,我试图在MakeOrderedPairSet
的主体内绑定到X.t
然而,我不知道如何把所有的东西组合在一起
(ORDERED\u PAIR\u SET\u TYPE with TYPE el=X.t)
是我能想到的最明显的表达方式,“给我一个与此类似的签名,但用一个具体的类型替换了一个抽象类型(或者在本例中是不同的抽象类型)”。但是,在这种情况下,它在语法上是无效的(因为有括号)。去掉括号也不会产生有效的“模块语言级表达式”;我开着它是因为我觉得它让我的意图更加明显
所以。。。如何使用命名签名来限制[functor生成的模块]/[parameterized module]的可见性?如果不想将
el
添加到模块的导出中,则有两种方法:
el:=X.t类型的有序\u对\u集\u类型
这将从签名中删除el
的规范(* orderedPairSetInlineSig.ml *)
module type ORDERED_TYPE = sig
type t
val compare : t -> t -> int
end
module MakeOrderedPairSet (X : ORDERED_TYPE) :
sig
type t
val get_fst : t -> X.t
val get_snd : t -> X.t
val make : X.t -> X.t -> t
val compare : t -> t -> int
end = struct
type t = X.t * X.t
let combine_comparisons fst snd =
if fst = 0 then snd else fst
let compare (x, y) (a, b) =
let cmp = X.compare x a in
let cmp' = X.compare y b in
combine_comparisons cmp cmp'
let get_fst ((x, y) : t) = x
let get_snd ((x, y) : t) = y
let make x y = (x, y)
end
模块集\类型(X:有序\类型)=
结构
模块类型S=
信号
t型
val get_fst:t->X.el
val get_snd:t->X.el
val make:X.el->X.el->t
val比较:t->t->int
结束
结束
有了这些,你可以写:
模块MakeOrderedPairSet(X:ORDERED类型):SET类型(X).S=。。。
如果您不想将
el
添加到模块的导出中,则有两种方法:
el:=X.t类型的有序\u对\u集\u类型
这将从签名中删除el
的规范(* orderedPairSetInlineSig.ml *)
module type ORDERED_TYPE = sig
type t
val compare : t -> t -> int
end
module MakeOrderedPairSet (X : ORDERED_TYPE) :
sig
type t
val get_fst : t -> X.t
val get_snd : t -> X.t
val make : X.t -> X.t -> t
val compare : t -> t -> int
end = struct
type t = X.t * X.t
let combine_comparisons fst snd =
if fst = 0 then snd else fst
let compare (x, y) (a, b) =
let cmp = X.compare x a in
let cmp' = X.compare y b in
combine_comparisons cmp cmp'
let get_fst ((x, y) : t) = x
let get_snd ((x, y) : t) = y
let make x y = (x, y)
end
模块集\类型(X:有序\类型)=
结构
模块类型S=
信号
t型
val get_fst:t->X.el
val get_snd:t->X.el
val make:X.el->X.el->t
val比较:t->t->int
结束
结束
有了这些,你可以写:
模块MakeOrderedPairSet(X:ORDERED类型):SET类型(X).S=。。。
一旦缺少定义
type el=X.t
的问题得到解决,你的例子对我来说很有用(有括号和没有括号)?@octachron是。。。将显式的类型el=X.t
添加到方法体中确实会使OCaml程序有效,但它也会将新导出的类型添加到接口中。。。因此,这并不完全等同于将第一个示例中的匿名接口“移动”到函子定义之外。一旦缺少定义type el=X.t
的问题得到解决,您的示例对我有效(带括号和不带括号)?@octachron是的。。。将显式的类型el=X.t
添加到方法体中确实会使OCaml程序有效,但它也会将新导出的类型添加到接口中。。。因此,它并不完全等同于在第一个示例中将匿名接口“移动”到函子定义之外。。。这是否意味着您可以在SML中编写参数化签名,而无需使用包装器模块?不,SML根本没有这种能力(尽管某些SML方言允许您编写类似于上述的内容)。为了进行比较。。。这是否意味着您可以在SML中编写参数化签名而无需使用包装器模块?不,SML根本没有这种能力(尽管某些SML方言允许您编写类似于上述内容的内容)。