使用.mli文件和Map

时间:2017-02-19 19:24:06

标签: dictionary types interface ocaml

我已经阅读了一些类似的问题和一些在线示例,但我仍然不知道在这种特殊情况下如何编写.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

with interface:

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

有没有办法编写一个让我能做我想做的事情的界面,而不是评论中的“冗余”界面?

1 个答案:

答案 0 :(得分:0)

如评论中所述,在实例化仿函数时,无法避免接口(mli文件)和实现(ml文件)之间的冗余。

您可以做的最好的事情如下:

$ cat dataStr.mli:

module IntMap : Map.S with type key = int
type couple = int * int
type int2couple = couple IntMap.t
module Couples : sig type t = int2couple end

$ cat dataStr.ml:

module IntOrder =
  struct
      type t = int
      let compare = Pervasives.compare
  end

module IntMap = Map.Make( IntOrder )

type couple = int * int
type int2couple = couple IntMap.t
module Couples = struct type t = int2couple end