我试图编写一个带有一对有序东西的仿函数,并生成另一个有序的东西(按字典顺序定义排序)。
但是,我希望得到的"有序类型"是抽象的,而不是OCaml元组。
这很容易与内联/匿名签名一起使用。
(* 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_PAIR_SET_TYPE
这样的名称,并将其移到MakeOrderedPairSet
的定义之外,就像这样(警告:语法无效):
(* orderedPairSet.ml *)
module type ORDERED_TYPE = sig
type t
val compare : t -> t -> int
end
module type ORDERED_PAIR_SET_TYPE = sig
type t
type el
val get_fst : t -> el
val get_snd : t -> el
val make : el -> el -> t
val compare : t -> t -> int
end
module MakeOrderedPairSet (X : ORDERED_TYPE) :
(ORDERED_PAIR_SET_TYPE with type el = X.t) = 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
el
是签名中的抽象类型,我试图绑定到X.t
正文中的MakeOrderedPairSet
。
但是,我无法弄清楚如何将所有东西放在一起。
(ORDERED_PAIR_SET_TYPE with type el = X.t)
是我能想到的最明显的方式"给我一个像这样的签名,但抽象类型被一个具体的(或不同的)取代 - 在这种情况下抽象)"。但是,在这种情况下,它在语法上无效(因为括号)。取下括号不会产生有效的"模块语言级表达式"要么;我把它留下来是因为我认为它使我的意图更加明显。
那么......你如何使用命名签名来限制[由仿函数生成的模块] / [参数化模块]的可见性?
答案 0 :(得分:2)
If you don't want to add el
to the exports of the module then there are two ways:
Use a substitution constraint:
ORDERED_PAIR_SET_TYPE with type el := X.t
That will remove the specification of el
from the signature.
Use a parameterised signature. Unfortunately, that is not expressible directly in OCaml, but requires a bit of extra functor gymnastics around the definition of your signature:
module SET_TYPE (X : ORDERED_TYPE) =
struct
module type S =
sig
type t
val get_fst : t -> X.el
val get_snd : t -> X.el
val make : X.el -> X.el -> t
val compare : t -> t -> int
end
end
With that you can write:
module MakeOrderedPairSet (X : ORDERED_TYPE) : SET_TYPE(X).S = ...