Functional programming Ocaml中的函子

Functional programming Ocaml中的函子,functional-programming,ocaml,functor,Functional Programming,Ocaml,Functor,我对函子(以及它的结果类型)有点问题。下面,我有一个使用有序类型的集合函子。实际上,我使用了ocaml附带的set.ml作为一些指导,但我似乎做的每件事都很好。我创建了一个带整数的有序模块,并将其应用于Set functor,以获取此代码示例中的最后一个模块IntSet 当我尝试插入整数时,下一行失败。我得到以下类型错误: Error: This expression has type int but is here used with type SetInt.elt = Se

我对函子(以及它的结果类型)有点问题。下面,我有一个使用有序类型的集合函子。实际上,我使用了ocaml附带的
set.ml
作为一些指导,但我似乎做的每件事都很好。我创建了一个带整数的有序模块,并将其应用于Set functor,以获取此代码示例中的最后一个模块IntSet

当我尝试插入整数时,下一行失败。我得到以下类型错误:

Error: This expression has type int but is here used with type
         SetInt.elt = Set(OrdInt).elt
别误会,这里的打字系统是正确的。顶层报告说
SetInt.elt
的类型是
Set(OrdInt).elt
,但当我使用ocaml提供的设置集执行相同的操作时,“相同”行是,
SetInt.elt=OrderedInt.t
。似乎我应该得到
SetInt.elt=Ordered.t

这太简单了,我可能只是错过了一些愚蠢的细节!啊

请注意:我已经简化了这里的成员/插入函数,因为这个问题与类型有关

module type Ordered =
  sig
    type t 
    val lt : t -> t -> bool
    val eq : t -> t -> bool
    val leq : t -> t -> bool
  end

module type S =
  sig
    type elt
    type t
    exception Already_Exists
    val empty  : t
    val insert : elt -> t -> t
    val member : elt -> t -> bool
  end

module Set (Elt:Ordered) : S = 
  struct
    type elt = Elt.t
    type t = Leaf | Node of t * elt * t
    exception Already_Exists
    let empty = Leaf
    let insert e t = t
    let member e t = false
  end

module OrdInt : Ordered =
  struct
    type t = int
    let lt a b = a < b
    let eq a b = a = b
    let leq a b = a <= b
  end

module IntSet = Set (OrdInt)

(* line that fails *)
let one_elm = IntSet.insert 1 IntSet.empty
已订购的模块类型=
信号
t型
val lt:t->t->bool
val eq:t->t->bool
val leq:t->t->bool
结束
模块类型S=
信号
英语四级考试
t型
异常已存在
val空:t
val插入:elt->t->t
val成员:elt->t->bool
结束
模块集(Elt:有序):S=
结构
类型elt=elt.t
类型t=叶| t*elt*t的节点
异常已存在
让空=叶
让我们插入e t=t
设成员et=false
结束
模块OrdInt:已订购=
结构
类型t=int
设lt a b=a让leq a b=a您需要更改这两条线

module Set (Elt:Ordered) : S = 
module OrdInt : Ordered =

如果没有这些,模块将不会有将类型elt和t公开为int的签名

[编辑]: set.ml没有'with'位,因为有一个sml.mli,它声明了函子的签名,并且确实有'with'。此外,如果没有明确指定签名,OrdInt不需要“with”,如下所示:

module OrdInt =
您还可以通过就地定义模块来构造集合:

module IntSet = Set (struct
 type t = int
 let lt a b = a < b
 let eq a b = a = b
 let leq a b = a <= b
end) 
module IntSet=Set(结构
类型t=int
设lt a b=amodule IntSet = Set (struct
 type t = int
 let lt a b = a < b
 let eq a b = a = b
 let leq a b = a <= b
end)