find_first 函数如何用于 OCaml 集合?

How does find_first function work for an OCaml Set?

我很难理解为什么以下代码找不到任何匹配结果:

module IntPairs =
struct
  type t = int * int
  let compare (x0,y0) (x1,y1) =
    match Stdlib.compare x0 x1 with
      0 -> Stdlib.compare y0 y1
    | c -> c
end
module PairsSet = Set.Make(IntPairs) 
let m2 = PairsSet.(empty |> add (2,0) |> add (1,2) |> add (0,1)) 
let result = PairsSet.find_first_opt (fun (input,value) -> print_endline ("arg:"^(string_of_int input)^" val:"^(string_of_int value)); input=0) m2;;
match result with
| None -> "nope"
| Some _ -> "yep";;

我根据文档的理解: https://ocaml.org/api/Set.S.htmlfind_first 函数应该从最小的元素(在本例中是 (0,1) 对)开始遍历,检查是否有任何元素满足提供的函数中的条件。

但是它并不像上面描述的那样工作,因为它从最大的元素 (2,0) 开始并且只检查这个元素。我已经检查了所提供元素的顺序是否对 find_first 函数的工作方式有任何影响,并且确实如此。如果我重新排列 m2 集,使 (0,1) 元素位于第一个,则会找到一个匹配项。

这也让我有些困惑,但这里的关键在于“f 是一个单调递增的函数”。

A monotonically increasing function 是一个不能减少的函数(尽管它的名字不一定增加)。对于返回 bool 的函数,就像我们这里所说的那样,这意味着它不能随着输入值的增加从 true 变为 false

您的函数 fun (input, value) -> input = 0true 仅针对单个值。对于任何低于 0 的值和任何大于 0.

的值都是假的

find_first 的实现方式是“向下”走 f returns true,“向上”走 returns false,从而找到 f returns true.

的第一个元素

如果您改为使用函数 fun (input, value) -> input >= 0,您会发现它会如您所愿地工作。