Ocaml中记录内的容器

Ocaml中记录内的容器,ocaml,containers,records,Ocaml,Containers,Records,我心目中的数据结构包括一个记录,其中包含一个存储唯一字符串的成员。 抽象地说,这就是我心目中的记录: struct A { name: string; neighbors: Set of String; }; 但我似乎无法在Ocaml中的记录中创建集合容器。鉴于集合是一个函子而不是传统类型,我不确定如何才能做到这一点。Set是一个函子,它为您想要的每种集合类型实例化一个新类型;因为它需要知道比较函数,所以不能像处理字符串列表那样处理字符串集(除非使用多态集from或extlib)。因此: 对于

我心目中的数据结构包括一个记录,其中包含一个存储唯一字符串的成员。 抽象地说,这就是我心目中的记录:

struct A {
name: string;
neighbors: Set of String;
};

但我似乎无法在Ocaml中的记录中创建集合容器。鉴于集合是一个函子而不是传统类型,我不确定如何才能做到这一点。

Set
是一个函子,它为您想要的每种集合类型实例化一个新类型;因为它需要知道比较函数,所以不能像处理字符串列表那样处理字符串集(除非使用多态集from或extlib)。因此:

对于电池的多态集(请小心,因为它不会检查您是否使用相同的比较功能):


例如,您需要理解“字符串列表”与要构建的“字符串集”之间的区别

对于列表,类型为“列表”,因为构建列表时不需要了解列表的内容。对于集合,您需要日志(N)时间访问,对于该集合,您需要根据元素的顺序组织集合。所以,你需要能够比较它们。OCaml提供了一个默认的比较函数(Pervasives.compare),但该函数并不总是最好的:它使用起来很昂贵(例如,对于整数),而且它并不总是有效(它对值的结构使用字典顺序,这并不总是您想要的顺序)

在OCaml中,当一个类型依赖于一个值时,这是“集合”的情况,但也是“排序列表”的情况,则需要使用一个函子来定义该类型,并应用该函子来获取新类型

这就是此代码为您所做的:

模块StringSet=Set.Make(字符串)

相当于:

module StringSet = Set.Make(struct
  type t = string
  let compare = compare
end)
其中“let compare=compare”表示比较函数是默认函数(第二个比较是指pervisives.compare)。您可以直接使用“String”,因为String模块已经包含“type t=String”和“let compare=compare”

type record = {
    name: string;
    neighbors: string BatSet.t
};
module StringSet = Set.Make(struct
  type t = string
  let compare = compare
end)