我正在通过阅读在线教程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.是否可以拥有&#34;泛型&#34;适用于所有类型的平等运算符以及如何实现?如果不适用于所有类型,那么至少对于字符串和数字?
答案 0 :(得分: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
的汽车和cdr是eq?
而b
的{{1}} }} 不是。如果不知道程序在做什么就可以回答这个问题:等式谓词依赖于应用程序,语言可以做的最好的就是提供一个允许你构建一个的工具包。
答案 1 :(得分:0)
Scheme具有不相交的类型,并决定不进行通用比较。原因可能是
string-ref
或vector-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"))))