Module OCaml:设置模块

Module OCaml:设置模块,module,set,ocaml,Module,Set,Ocaml,我想使用OCaml生成数据集并对它们进行比较。我看过有关模块类型的文档,如Set.OrderType、Set.Make,但我不知道如何初始化集合或以其他方式使用它们。集合是使用函数接口定义的。对于任何给定类型,必须使用Set.Makefunctor为该类型创建Set模块。标准库的一个不幸疏忽是它们没有为内置类型定义Set实例。在大多数简单的情况下,使用pervisives就足够了。比较。这里有一个适用于int的定义: module IntSet = Set.Make( struct

我想使用OCaml生成数据集并对它们进行比较。我看过有关模块类型的文档,如
Set.OrderType
Set.Make
,但我不知道如何初始化集合或以其他方式使用它们。

集合是使用函数接口定义的。对于任何给定类型,必须使用
Set.Make
functor为该类型创建
Set
模块。标准库的一个不幸疏忽是它们没有为内置类型定义
Set
实例。在大多数简单的情况下,使用
pervisives就足够了。比较
。这里有一个适用于
int
的定义:

module IntSet = Set.Make( 
  struct
    let compare = Pervasives.compare
    type t = int
  end )
模块
IntSet
将实现
Set.S
接口。现在,您可以使用
IntSet
模块对集合进行操作:

let s = IntSet.empty ;;
let t = IntSet.add 1 s ;;
let u = IntSet.add 2 s ;;
let tu = IntSet.union t u ;;
请注意,您不必显式定义
Set的输入结构。将
设为
OrderedType
;类型推断将为您完成这项工作。或者,您可以使用以下定义:

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

module IntSet = Set.Make( IntOrder )
这样做的好处是,您可以重复使用相同的模块来实例化
映射

module IntMap = Map.Make( IntOrder )

因为元素的类型是固定的,所以在使用函子时会失去一些泛型。例如,您将无法定义一个函数,该函数接受某个任意类型的
,并对其执行某些操作。(幸运的是,
Set
模块本身声明了许多关于
Set
s的有用操作。)

除了Chris的回答之外,可以说一些标准库模块已经遵守了
OrderedType
签名。例如,您可以简单地执行以下操作:

module StringSet = Set.Make(String) ;;       (* sets of strings *)
module Int64Set = Set.Make(Int64) ;;         (* sets of int64s *)
module StringSetSet = Set.Make(StringSet) ;; (* sets of sets of strings *)
等等

下面是
StringSet
的一个简单用法示例;请记住,集合是功能数据结构,因此向集合添加新元素将返回一个新集合:

let set = List.fold_right StringSet.add ["foo";"bar";"baz"] StringSet.empty ;;
StringSet.mem "bar" set ;; (* returns true *)
StringSet.mem "zzz" set ;; (* returns false *)

“你将无法定义一个函数,它接受一个任意类型的集合。”但是,你可以通过在一个函子中定义函数来完成同样的事情,该函子将你的特定集合模块作为参数。当然,要使用它,程序员还必须用这个函子生成另一个模块,所以它不太方便。一路上都是函子。