我如何在 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
我想编写一个函数,给定一个非负整数 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