如何在ADT上定义多态比较?

时间:2019-02-13 18:26:15

标签: comparison ocaml algebraic-data-types

多态compare函数可用于实例化OCaml预定义的函子(Map.MakeSet.Make,...)。在这种情况下,我们只需要知道它的行为就像一个订单,但是了解它的实际定义可能会很有用。例如,如何确保以下函数正确计算列表的最大值:

let rec max_list = function
| [] -> None
| h::t -> max (Some h) (max_list t)

我首先认为,早先定义的构造函数小于后来定义的构造函数。但是,事实并非如此,因为 max Non (Som 2)Som 2 : opt opt是否定义为 type 'a opt = Non | Some of 'a 或作为 type 'a opt = Some of 'a | Non

要比较代数数据类型的值,我希望它比较构造函数,然后,如果它们相同,则比较它们的参数。为什么不正确?如何定义比较?

1 个答案:

答案 0 :(得分:1)

如果您查看compare函数和前面的比较运算符(当前为https://caml.inria.fr/pub/docs/manual-ocaml-4.08/core.html#sec551)的语言定义,您会发现没有明确保证a的不同构造函数的顺序。变体类型。仅保证它代表总订单。

如果需要特定的订单,则需要定义自己的比较函数。

在当前实现中,不带参数的构造函数(空构造函数)被视为小于带参数的构造函数,即使它们出现在定义的后面。我认为,仅靠这一点是不明智的,因为语言定义中没有明确的保证。

# type ab = B of int | A;;
type ab = B of int | A
# A < B 2;;
- : bool = true
# type cd = C | D of int;;
type cd = C | D of int
# C < D 2;;
- : bool = true
# type ef = E | F;;
type ef = E | F
# E < F;;
- : bool = true