我想使用OCaml生成数据集并在它们之间进行比较.我已经看过模块类型的文档,如Set.OrderType,Set.Make等,但我无法弄清楚如何初始化一个集合或以其他方式使用它们.
Chr*_*way 30
使用functorial接口定义集合.对于任何给定类型,您必须Set使用Set.Make仿函数为该类型创建模块.对标准库的不幸监督是它们没有Set为内置类型定义实例.在大多数简单的情况下,它足以使用Pervasives.compare.这是一个适用于以下内容的定义int:
module IntSet = Set.Make(
struct
let compare = Pervasives.compare
type t = int
end )
Run Code Online (Sandbox Code Playgroud)
该模块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 ;;
Run Code Online (Sandbox Code Playgroud)
请注意,您不必显式定义输入结构Set.Make作为OrderedType; 类型推断将为您完成工作.或者,您可以使用以下定义:
module IntOrder : Set.OrderedType = struct
type t = int
let compare = Pervasives.compare
end
module IntSet = Set.Make( IntOrder )
Run Code Online (Sandbox Code Playgroud)
这样做的好处是您可以重复使用相同的模块来实例化Map:
module IntMap = Map.Make( IntOrder )
Run Code Online (Sandbox Code Playgroud)
你在使用仿函数时失去了一些通用性,因为元素的类型是固定的.例如,您将无法定义一个采用Set某种任意类型并对其执行某些操作的函数.(幸运的是,Set模块本身在Sets 上声明了许多有用的操作.)
Bru*_*ine 12
除了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 *)
Run Code Online (Sandbox Code Playgroud)
等等.
这是一个简单的用法示例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 *)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11576 次 |
| 最近记录: |