使用Set.Make.iter转换集合的元素?

时间:2014-11-23 16:17:06

标签: data-structures iterator set ocaml

我有一个实现了一个集合的库(这里有文档的接口:http://pastebin.com/j9QUyN1G)。我理解除了这个片段之外的一切:

val iter : ('a -> unit) -> 'a t -> unit 
(** [iter f s] applies [f] to all elements in set [s].  The elements
    are passed to [f] in increasing order with respect to the ordering
    used to create the set. *)

所以iter将一个函数作为其中一个参数并将其应用于集合的所有元素。所以我希望像('a -> 'a)之类的东西采用集合的元素并将其更改为具有其他值的相同类型的元素,或者('a -> 'b)将其转换为'a t并将其转换为{{1} }}。但是,'b t采用iter类型的函数并返回('a -> unit),而不是unit'a t

那么示例函数应该如何传递给'b t

3 个答案:

答案 0 :(得分:3)

iter不会更改集合的元素。它的纯粹是因为它的副作用而被执行。您可以使用它来打印元素,例如:

module StringSet = Set.Make(String)
…
StringSet.iter print_endline ss

设置数据结构是不可变的,因此您无法更改集合的元素。您可以构建一个新元素集,其元素派生自现有集合。对于列表,函数map采用列表[x1; …; xn]并返回新列表[f x1; …; f xn]Set模块中没有类似的功能,因为集合中的元素没有按照调用者选择的顺序存储:没有集合的元素,其元素的顺序来自另一个集合。如果要根据集合元素的图像构建集合,请逐个插入新元素。

module Int = struct
  type t = int
  let compare = Pervasives.compare
end
module IntSet = Set.Make(Int)
module StringSet = Set.Make(String)
let int_to_string_set is =
  IntSet.fold (fun i ss -> StringSet.add (string_of_int i) ss) is StringSet.empty

答案 1 :(得分:1)

iter接受这样的函数,即接受'a类型的参数,无论它是什么,都返回类型为unit的值。换句话说,它被评估副作用,因为它不能返回任何有价值的东西。

您正在寻找的是map函数,它通常接受类型'a -> 'b的函数,该函数具有类型为'a的元素,并返回一个包含元素的容器输入'b。不幸的是,你所展示的界面并没有提供这样的功能。但这不是问题,因为它提供了fold函数,这是最常用的迭代器。只有fold你可以实现任何其他iteratos,例如mapiterexists等等......确实在Core库中你可以找到{{} 1}}仿函数将自动从一个函数 - Container.Make派生一个公共容器接口。但是,您也可以自己定义地图:

fold

答案 2 :(得分:0)

这将是一个带副作用的函数,如下所示:

Let p x = Printf.printf "%d\n" x