问题
我遇到的一个问题是将两个模块的类型和值带入一个新的组合模块。我举个例子。目前我有以下两种类型签名
module type Ordered =
sig
type t (* the type of elements which have an order *)
val eq : t * t -> bool
val lt : t * t -> bool
val leq : t * t -> bool
end
module type Stack =
sig
exception Empty
type 'a t (* the type of polymorphic stacks *)
val empty : 'a t
val isEmpty : 'a t -> bool
val cons : 'a * 'a t -> 'a t
val head : 'a t -> 'a
val tail : 'a t -> 'a t
end
我想创建一个“为其订购基本元素的堆栈”模块,即
module type OrderedStack =
sig
exception Empty
type elem (* the type of the elements in the stack *)
val eq : elem * elem -> bool
val lt : elem * elem -> bool
val leq : elem * elem -> bool
type t (* the type of monomorphic stacks *)
val empty : t
val isEmpty : t -> bool
val cons : elem * t -> t
val head : t -> elem
val tail : t -> t
end
到这里为止,一切都很好,很整洁。但是现在,我想编写一个函子,它接受一个 Ordered 模块和一个 Stack 模块并生成一个 OrderedStack 模块。就像是
module My_functor (Elem : Ordered) (St : Stack): OrderedStack =
struct
exception Empty
type elem = Elem.t
let eq = Elem.eq
let lt = Elem.lt
let leq = Elem.leq
type t = elem St.t
let empty = St.empty
let isEmpty = St.isEmpty
let cons = St.cons
let head = St.head
let tail = St.tail
end
这正是我想要的并且是正确的。但它看起来像一个可怕的键盘浪费。
我的问题
上面有没有更紧凑的写法My_functor
?
我发现但无法投入使用的内容
我已经看到了include
可以编写如下指令的指令:
module my_functor (Elem : Ordered) (St : Stack): OrderedStack =
struct
include Elem
include St
end
但这有一个问题,对于我上面的两个特定模块,Ordered 和 Stack 都有相同的type t
(尽管它们在每个模块中意味着不同的东西)。我不希望更改 and 的原始定义,Ordered
因为Stacks
它们已经在代码中的许多部分中使用,但是如果您找到原始两个模块的替代公式使其工作,那很好。
我还看到with
操作符在这里可能是相关的,但我不太清楚应该如何使用它来产生所需的效果。我面临的问题是两个模块的类型t
和实际连接。'a t
Ordered
Stacks
有任何想法吗?