【问题标题】:Why are there separate comparison functions/operators for strings and numbers?为什么字符串和数字有单独的比较函数/运算符?
【发布时间】:2016-10-17 05:31:08
【问题描述】:

通过阅读在线教程Write Yourself a Scheme in 48 Hours,我正在慢慢学习Scheme和修改Haskell。我刚上this 部分,它向我们介绍了Scheme 中的一些比较运算符。

("=", numBoolBinop (==)),
("<", numBoolBinop (<)),
(">", numBoolBinop (>)),
("/=", numBoolBinop (/=)),
(">=", numBoolBinop (>=)),
("<=", numBoolBinop (<=)),
("&&", boolBoolBinop (&&)),
("||", boolBoolBinop (||)),
("string=?", strBoolBinop (==)),
("string<?", strBoolBinop (<)),
("string>?", strBoolBinop (>)),
("string<=?", strBoolBinop (<=)),
("string>=?", strBoolBinop (>=)),

我有几个新手问题。 1. 为什么不同类型有单独的比较运算符,而不是一个泛型运算符或一个有许多重载的运算符? 2. 是否有可能有一个适用于所有类型的“通用”相等运算符以及如何实现?如果不是针对所有类型,那么至少针对字符串和数字?

【问题讨论】:

    标签: generics polymorphism scheme operators lisp


    【解决方案1】:

    只回答第二个问题:不,不是。首先,eq? 和任何其他相等谓词之间存在差异,eq? 几乎不可避免地对数字有不可靠的行为。所以你至少需要eq? 和一个“语义”相等谓词。但是这样的语义相等谓词是不存在的,因为语言不知道你想要什么语义。例如,这应该返回什么?

    (let ([c (cons #f #f)])
      (let ([a (cons c c)]
            [b (cons (cons #f #f) (cons #f #f))])
        (general-semantic-equal? a b)))
    

    嗯,它应该返回 true 还是 false 取决于 在程序中是否重要 a 的 car 和 cdr 是 eq?b 的不是。这个问题不是在不知道程序在做什么的情况下就可以回答的:等式谓词是依赖于应用程序的,语言能做的最好的事情就是提供一个工具包,让您可以构建一个。

    【讨论】:

      【解决方案2】:

      Scheme 具有不相交的类型,因此决定不进行泛型比较。原因可能是

      1. 标准没有任何方法覆盖
      2. 从历史上看,我们使用 string-refvector-ref 之类的东西,而不是一个通用的 ref

      所以它没有通用的比较程序是很自然的。唯一的例外是数字比较程序。

      正如我上面提到的,Scheme 标准没有任何方法覆盖机制,但是不可能制作通用过程。您只需在 Tiny CLOS 等其他面向对象的库上构建它们。

      如果你只需要字符串和数字,你也可以这样做:

      (define (generic= n/s1 n/s2 . rest)
        (cond ((for-all number? (cons* n/s1 n/s2 rest))
               (apply = n/s1 n/s2 rest))
              ((for-all string? (cons* n/s1 n/s2 rest))
               (apply string=? n/s1 n/s2 rest))
              (else (assertion-violation 'generic= "type not supported"))))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-21
        • 2012-02-09
        • 2013-05-29
        • 2017-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多