我如何在 OCaml 中使用集合?

How do I use sets in OCaml?

我想编写一个函数,给定一个非负整数 n,returns {1,...,n} 的幂集。所以我想使用找到的 Set.S 模块 here。但我似乎无法导入它。当我运行以下代码时:

open Set.S

let rec power_set n =
  if n = 0 then add empty empty else union (iter (add n s) power_set (n-1)) (power_set (n-1));;

let print_set s = SS.iter print_endline s;;

print_set (power_set 2)

我收到错误:

File "countTopologies.ml", line 1, characters 5-10:
Error: Unbound module Set.S

也许我的计算机上没有安装 Set.S 模块? (我只完成了安装 OCaml 所需的基本工作)。如果是这种情况,我将如何获得它?

您必须 Make 来自 Set 函子的 set 模块。

module SI = Set.Make(struct type t = int let compare = compare end)

那么你可以有一组整数:

# let myset = SI.add 3 SI.empty;;
val myset : SI.t = <abstr>
# SI.elements myset;;
- : SI.elt list = [3]

Set.S 模块类型 ,不是模块。您只能打开模块。实际上,模块 Set 包含三个元素:

  • 表示实现有序类型的模块类型的模块类型OrderedType
  • 模块类型S表示实现Set数据结构的模块类型;
  • 仿函数 Make 接受类型 OrderedType 的模块和 returns 接受类型 S.
  • 的模块

要获得集合模块,您需要使用 Set.Make 仿函数创建它。仿函数有一个参数——集合元素的模块。在现代 OCaml (4.08+) 中,您可以为整数创建一个集合模块,就像

module Ints = Set.Make(Int)

然后你就可以这样使用了,

让数字 = Ints.of_list [1;2;3] assert (Ints.mem 2 个数字)

对于旧版本的 OCaml,它不提供 Int 模块,或者对于非标准(自定义)类型,您需要定义自己的模块来实现 OrderedType 接口,例如,

 module Int = struct 
   type t = int 
   (* use Pervasives compare *)
   let compare = compare
 end

 module Ints = Set.Make(Int)

您还可以使用非标准库,例如 Janestreet 的核心库,它提供开箱即用的集合。 Core 库有一个 Int 模块,它已经包含集合、映射、哈希表,因此无需任何函子即可访问它:

open Core.Std

let nil = Int.Set.empty

或者,在现代(2018-2019)版本的 Janestreet Core 或 Base 库中,您可以使用多态 sets/maps,这要求您仅在新的集合或映射是创建,例如,像这样

open Base (* or Core, or Core_kernel *)

let nil = Set.empty (module Int)
let one = Set.add nil 1
let two = Set.singleton (module Int) 2