如何在OCaml中使用集合?

时间:2016-06-21 17:50:28

标签: module ocaml

我想写一个函数,给定一个非负整数n,返回{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所需的骨架)。如果是这种情况,我将如何获得它?

2 个答案:

答案 0 :(得分:8)

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

  • 模块类型OrderedType,它是一种实现有序类型的模块;
  • 模块类型S,它是一种实现Set数据结构的模块;
  • 仿函数Make,它接受​​OrderedType类型的模块并返回S类型的模块。

例如,要创建一个实现整数集的模块,您可以执行以下操作:

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

 module Ints = Set.Make(Int)

其他库,如Janestreet的核心库,提供开箱即用的集合,例如,核心库有一个Int模块,已经收集了集合,地图,哈希表,所以它可以在没有任何仿函数的情况下访问:

open Core.Std

let nil = Int.Set.empty

或者,在Janestreet Core或Base库的现代(2018-2019)版本中,您可以使用多态集/映射,这需要您仅在创建新集或映射时指定键的模块,例如,像这样

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

答案 1 :(得分:3)

您必须{Set}仿函数Make设置模块。

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]