Ocaml 是否比较所有类型的工作? 让我们考虑一个类型 t>代码>两个变量 x,y>代码>类型 t>代码>

Ocaml 是否比较所有类型的工作? 让我们考虑一个类型 t>代码>两个变量 x,y>代码>类型 t>代码> ,ocaml,Ocaml,调用compare x y是否对任何类型的t有效?我找不到任何反例。它不适用于函数类型: # compare (fun x -> x) (fun x -> x);; Exception: Invalid_argument "equal: functional value". 同样,它(通常)不适用于其值可以包含函数的其他类型: # type t = A | B of (int -> int);; type t = A | B of (int -> int) # comp

调用
compare x y
是否对任何类型的
t
有效?我找不到任何反例。

它不适用于函数类型:

# compare (fun x -> x) (fun x -> x);;
Exception: Invalid_argument "equal: functional value".
同样,它(通常)不适用于其值可以包含函数的其他类型:

# type t = A | B of (int -> int);;
type t = A | B of (int -> int)
# compare A A;;
- : int = 0
# compare (B (fun x -> x)) A;;
- : int = 1
# compare (B (fun x -> x)) (B (fun x -> x));;
Exception: Invalid_argument "equal: functional value".
它(通常)也不适用于递归值:

#类型t={self:t};;
类型t={self:t;}
#设recv={self=v};;
val v:t={self=}
#设rec v'={self=v'};;
val v':t={self=}
#比较v;;
-:int=0
#比较v′;;
(*不终止。*)
这些情况也列在
pervisives

中的for
compare
中。多态比较函数通过递归探索值的结构来工作,提供OCaml值的特殊总排序,用于定义由多态=运算符测试的结构相等性

正如@antron所观察到的那样,它在设计上并没有定义在函数和闭包上。该定义的递归性质意味着不在包含函数或闭包的值上定义结构等式。这种递归性质还意味着compare函数不是在递归值上定义的,正如@antron所提到的那样

结构相等,因此比较函数和比较运算符不知道结构不变量,不能用于比较(轻度)高级数据结构,如集合、映射、hashtbl等。如果需要对这些结构进行比较,则必须编写专门的函数,这就是Set和Map定义此类函数的原因

定义自己的结构时,一个好的经验法则是区分

  • 具体类型,仅根据基本类型和其他具体类型定义。混凝土类型不应用于处理需要一些不变量的结构,因为很容易创建这种类型的任意值来破坏这些不变量。对于这些类型,多态比较函数和运算符是合适的

  • 抽象类型,其具体定义是隐藏的。对于这些类型,最好提供专门的比较功能。定义了可用于从专用比较函数的实现中派生比较运算符的。其用途如图所示


此外,多态的
compare
=
对于可能具有不同表示的值(例如,应用
Set
Map
生成的类型)不起作用。它对对象也不起作用。它比较每个对象的唯一数字ID。因此,对物理上不同的两个对象进行比较,例如
compare(object end)(object end)
永远不会返回0。@PascalCuoq,MartinJambon:但这取决于您对“work”的定义。他们从未保证它会遵循你的平等观念。它只需要遵循一些(未指定的)一致的顺序。
# type t = {self : t};;
type t = { self : t; }
# let rec v = {self = v};;
val v : t = {self = <cycle>}
# let rec v' = {self = v'};;
val v' : t = {self = <cycle>}
# compare v v;;
- : int = 0
# compare v v';;
(* Does not terminate. *)