13

我对仿函数(它是结果类型)有点问题。下面,我有一个使用 Ordered 类型的 Set 仿函数。我实际上使用了set.mlocaml 附带的一些指导,但我似乎做的一切都是对的。我创建了一个带整数的 Ordered 模块,并将其应用于 Set 函子,以获取此代码示例中的最后一个模块 IntSet。

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

Error: This expression has type int but is here used with type
         SetInt.elt = Set(OrdInt).elt

不要误会我的意思,这里的类型系统是正确的。顶层报告的类型SetInt.eltSet(OrdInt).elt,但是当我使用 ocaml 提供的设置执行相同的操作来设置 Set 时,“相同”行是 , 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
4

1 回答 1

15

您需要更改这两行

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

module Set (Elt:Ordered) : S with type elt = Elt.t = 
module OrdInt : Ordered with type t = int =

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

[编辑]:set.ml 没有“with”位,因为有一个 sml.mli,它声明了函子的签名并且它确实有“with”。此外,如果您没有明确指定 OrdInt 的签名,则 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) 
于 2009-03-12T21:24:17.560 回答