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