ocaml:创建多态类型集

时间:2014-07-27 17:29:36

标签: module ocaml

在一个模块中,我定义了一个表示图形节点的类型,它具有多态数据字段,即

type 'a t = {data: 'a; adj: 'a t list}

如何创建Set这些数据?我尝试了以下内容(根据其中一条建议here

let cmp (g1:int Graph.t) (g2: int Graph.t) : int=
  if phys_equal g1 g2 then
    0
  else
    Int.compare g1.data g2.data

let make_set () =
    let module Ord=struct
      type t=int Graph.t
      let compare=cmp
    end
    in (module Set.Make(Ord): Set.S with type elt=Ord.t) 

但是,当我这样做时,我得到“由'带有'的签名没有名为elt的组件”

2 个答案:

答案 0 :(得分:1)

我不确定你要做什么,但如果你只想制作数据类型为int的节点集,你不需要使用比通常的OCaml更高级的东西。模块操作。

以下代码适用于我:

module Graph =
struct
    type 'a t = {data: 'a; adj: 'a t list}
end

let cmp (g1:int Graph.t) (g2: int Graph.t) : int =
    if g1 == g2 then
        0
    else
        compare g1.Graph.data g2.Graph.data

module GSet = Set.Make(struct type t = int Graph.t let compare = cmp end)

这是一段代码会话:

$ ocaml
        OCaml version 4.01.0

# #use "g.ml";;
module Graph : sig type 'a t = { data : 'a; adj : 'a t list; } end
val cmp : int Graph.t -> int Graph.t -> int = <fun>
module GSet :
  sig
    type elt = int Graph.t
    . . .
  end
# let myset = GSet.add { Graph.data = 14; adj = [] } GSet.empty;;
val myset : GSet.t = <abstr>
# GSet.is_empty myset;;
- : bool = false

我没有理由限制模块类型,因为Set.S已经是Set.Make返回的模块类型。但我不是OCaml模块类型的复杂用户。

答案 1 :(得分:1)

对于我来说,该代码在解释器中工作正常。也许您在Set中未定义elt类型的情况下打开了另一个S模块?

如果我在解释器中定义以下Set

# module Set = struct
      module type S = sig end
  end;;
module Set : sig module type S = sig  end end

然后在编写时简单地重新定义make_set,我实际上得到了相同的错误消息。在使用解释器尝试代码时,请始终牢记您可能正在使用之前编写的定义。

  • 根据经验,尽量避免将值绑定到您希望使用的库中已使用的名称(我知道在那里缩短您的名字很有吸引力,但至少要添加一个小的独特前缀 - 例如,在您的情况下使用ISet而不是Set

  • 您始终可以将代码作为脚本运行,即从命令行启动它,如下所示:

    $ ocaml my_script.ml
    

或者通过解释器提示符处的#use指令。这使您可以在使用新的ocaml环境测试代码片段之前编写代码片段。

最后,正如@ Jeffrey提供的答案一样,一个解压缩的模块足以满足大多数用途;你的代码是关于实例化一个第一类模块,如果你打算在不使用仿函数的情况下传递该模块,那么这只是有趣的。有关进一步说明,请参阅documentation模块(以及该语言的相关extensions)。