标准ML中的结构比较

nic*_*las 2 ml sml comparison-operators

我似乎无法找到为什么这不起作用的参考:

- (2000,1)<(2000,1);    
stdIn:18.1-18.18 Error: operator and operand don't agree [overload]
  operator domain: 'Z * 'Z
  operand:         (int * int) * (int * int)
  in expression:
    (2000,1) < (2000,1)
Run Code Online (Sandbox Code Playgroud)

标准ML是否支持结构比较?

Jes*_*erg 5

简短回答:仅限于平等.

顶级环境中的严格小于运算符(<)与其他比较运算符有点"特殊".它们是"特殊的",因为它们(作为唯一的)重载以使用整数,实数等.此重载的一些特殊之处是如果无法推断类型,则使用整数(例如,推断出多态类型'a).

对于整数的情况,使用Int.<函数,它只使用两个整数作为参数

- Int.<;
val it = fn : int * int -> bool
Run Code Online (Sandbox Code Playgroud)

但是对于相等,情况有点不同,正如等于运算符的类型所示

- op=;
val it = fn : ''a * ''a -> bool
Run Code Online (Sandbox Code Playgroud)

在这里看到多态类型''a,注意双重.这是因为它只能实例化为相等类型(例如,int,string,int'string等).请注意,real不是一个相等的类型!

更新

我通常做的事情是为我创建的每个(数据)类型创建一个比较函数.这样我就可以完全控制发生的事情.比较功能的想法是返回订单

datatype order = LESS | EQUAL | GREATER
Run Code Online (Sandbox Code Playgroud)

有了这个,您可以轻松地创建一个案例表达并执行适当的操作,而不是 if .. < .. then .. else ..

UPDATE1

下面的代码来自Andreas Rossberg的评论.我把它放在这里是为了方便阅读

fun comparePair compareA compareB ((a1, b1), (a2, b2)) =
    case compareA (a1, a2) of
      EQUAL => compareB (b1, b2)
    | other => other
Run Code Online (Sandbox Code Playgroud)

以及一些使用示例

- comparePair Int.compare String.compare ((2, "foo"), (3, "bar"));
val it = LESS : order
- comparePair Int.compare String.compare ((3, "bar"), (3, "bar"));
val it = EQUAL : order
Run Code Online (Sandbox Code Playgroud)