Проблема
Одна проблема, с которой я столкнулся, заключается в том, чтобы привести типы и значения двух модулей в новый комбинированный модуль. Я приведу пример. В настоящее время у меня есть следующие подписи двух типов
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
действительно подключены.
Любые идеи?
MonoStack
, так иOrdered
вместо подмодулей. Однако я предпочитаю решение с подмодулями - по крайней мере, потому, что я еще не использую 3.12. Одна приятная вещь с подмодулями заключается в том, что вы можете легко передать их другим функторам: о, мне нужно построить Set из элементов моего стека. - person gasche   schedule 30.01.2011