Я прочитал несколько подобных вопросов и некоторые онлайн-примеры, но я до сих пор не знаю, как написать файл .mli
в этом конкретном случае.Использование файлов .mli и карты
В моем проекте я использую общий модуль карты с ключами int, который затем я специализируюсь в зависимости от значений, которые я хочу сохранить. Скажем, я хочу использовать его для хранения пар, поэтому у меня есть такой файл :
file dataStr.ml:
module IntOrder =
struct
type t = int
let compare = Pervasives.compare
end
module IntMap = Map.Make(IntOrder)
type couple = int * int
(* pretty names *)
type int2couple = couple IntMap.t
module Couples = struct type t = int2couple end
файл, используя этот подмодуль будет:
file useMap.ml:
open DataStr
let use k m =
IntMap.add k ((Random.int 6), (Random.int 8)) m
с интерфейсом:
file useMap.mli:
open DataStr
val use : int -> Couples.t -> Couples.t
До сих пор, так хорошо.
Давайте теперь предположим, что хочу представить подмодуль Couples
, но не тип int2couple
. Я бы тогда написать этот интерфейс:
file dataStr.mli:
module IntMap : Map.S with type key = int
module Couples : sig type t end
(*
I'd like to avoid the redundancy of using
module Couples : sig type t = (int * int) IntMap.t end
*)
Проблема заключается в том, если я добавить этот интерфейс, я получаю эту ошибку компиляции:
Error: The implementation useMap.ml does not match the interface useMap.cmi:
Values do not match:
val use :
DataStr.IntMap.key ->
(int * int) DataStr.IntMap.t -> (int * int) DataStr.IntMap.t
is not included in
val use : int -> DataStr.Couples.t -> DataStr.Couples.t
Есть ли способ, чтобы написать интерфейс что позволяет мне делать то, что я хочу делать, кроме «лишнего» в комментарии?
Если инкапсулировать тип '(интермедиат * целое) IntMap.t' есть нет способа узнать внешний 'DataStr', который на самом деле является картой. – mookid
И я догадываюсь, что этот уровень инкапсуляции не достигает многого. Что вы хотите скрыть от кода клиента? – mookid
Я хотел бы просто показать «Пары», скрывая «int2couple» и, возможно, «пару», так как я создал их, чтобы использовать их 'dataStr.ml'. Нет особых причин для того, что я пытаюсь получить, кроме читаемости интерфейса. – pimple