【问题标题】:Structural comparison in Standard ML标准 ML 中的结构比较
【发布时间】:2013-01-02 15:39:34
【问题描述】:

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

- (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)

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

【问题讨论】:

    标签: sml ml comparison-operators


    【解决方案1】:

    简短的回答:仅用于平等。

    顶级环境中的严格小于运算符 ('a)。

    对于整数,使用Int.&lt; 函数,它只接受两个整数作为参数

    - Int.<;
    val it = fn : int * int -> bool
    

    但是对于相等,情况有点不同,从相等运算符的类型可以看出

    - op=;
    val it = fn : ''a * ''a -> bool
    

    这里的多态类型是蜜蜂''a,注意双标。这是因为它只能实例化为相等类型(例如,int、string、int'string 等)。请注意,real 不是相等类型!

    更新

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

    datatype order = LESS | EQUAL | GREATER
    

    有了这个,您可以轻松地制作一个 case 表达式并做适当的事情,而不是 if .. &lt; .. then .. else ..

    更新1

    以下代码来自 Andreas Rossberg 的评论。为了便于阅读,我将其包含在此处

    fun comparePair compareA compareB ((a1, b1), (a2, b2)) =
        case compareA (a1, a2) of
          EQUAL => compareB (b1, b2)
        | other => other
    

    以及一些使用示例

    - 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
    

    【讨论】:

    • 感谢您的链接,它非常有用。鉴于每个组件本身都是“可比的”,是否可以编写通用的字典顺序?例如,我的类型是类型 Date = int * int * int,“继承”字典顺序的最简洁方法是什么?
    • 是''一种硬连线的平等机制,还是泛化为'hashable''comparable'和其他潜在的用户定义机制?
    • @nicolas:不,相等是唯一具有特殊多态支持的运算符。要为配对构建字典顺序,您可以轻松编写一个组合器:fun comparePair compareA compareB ((a1, b1), (a2, b2)) = case compareA (a1, a2) of EQUAL =&gt; compareB (b1, b2) | other =&gt; other 并像 comparePair Int.compare String.compare ((2, "foo"), (3, "bar")) 一样使用它。这以显而易见的方式推广到各种其他多态类型(例如三元组、列表、树)或其他操作(如散列)。
    • Moscow ML Language Overview 的第 14 章(内置变量和函数)简要描述了这种重载是如何完成的。请注意,它是特定于 MosML 的,但我希望 SML/NJ 也能做到这一点。
    • 一个更有趣的例子,展示了它是如何任意组合的:List.collate (comparePair (comparePair Int.compare Int.compare) String.compare) ([...], [...])——也就是说,库已经提供了List.collate作为列表的通用字典比较函数。
    猜你喜欢
    • 2017-05-14
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多