問題
私が抱えている問題の 1 つは、2 つのモジュールの型と値を新しい結合モジュールに持ち込むことです。例を挙げます。現在、次の2つの型シグネチャがあります
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
しかし、これには、上記の特定の 2 つのモジュールの場合、Ordered と Stack の両方が同じであるという問題がありますtype t
(ただし、それぞれの意味は異なります)。Ordered
andの元の定義はStacks
コードの多くの部分で既に使用されているため、変更したくありませんが、元の 2 つのモジュールを機能させる別の定式化が見つかった場合は、それで問題ありません。
また、with
演算子がここで関連している可能性があることも確認しましたが、目的の効果を生み出すために演算子をどのように使用する必要があるかについてはよくわかりませんでした。私が直面している問題は、2 つのモジュールのタイプt
と実際に接続されていることです。'a t
Ordered
Stacks
何か案は?