Проблема
Одна проблема, с которой я столкнулся, - это перенести типы и значения двух модулей в новый комбинированный модуль.Я приведу пример.В настоящее время у меня есть следующие два типа подписей
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
(хотя в каждом из них они означают разные вещи).Я бы предпочел не менять исходное определение Ordered
и Stacks
, поскольку они уже используются во многих частях кода, но если вы найдете альтернативную формулировку для двух исходных модулей, которая заставит его работать, это нормально.
Я также видел, что оператор with
может быть уместен здесь, но я не мог понять, как его следует использовать для получения желаемого эффекта.Проблема, с которой я сталкиваюсь, заключается в том, что типы t
и 'a t
двух модулей Ordered
и Stacks
и фактически подключены.
Есть идеи?