【发布时间】:2011-05-07 08:32:07
【问题描述】:
在 scala 2.9.0.RC3 中,我为解析器定义了一个特征和一个解析器的具体示例:
trait Parser {
type Result
def parse(s: String): Result
}
class IdParser extends Parser {
case class Result(s: String)
def parse(s: String) = new Result(s)
}
现在我希望能够比较解析后的值:
class Comparator[P <: Parser](p: P) {
def compare(s1: String, s2: String) = p.parse(s1) == p.parse(s2)
}
这很好,我可以做到:
println(new Comparator(new IdParser).compare("a", "b"))
它会产生 false,正如预期的那样。不幸的是,它从这里开始走下坡路。为了更好地进行比较,我定义:
class CustomisableComparator[P <: Parser](p: P,
cmp: (P#Result, P#Result) => Boolean = (r1: P#Result, r2: P#Result) => r1 == r2) {
def compare(s1: String, s2: String) = cmp(p.parse(s1), p.parse(s2))
}
并尝试像以前一样调用它:
println(new CustomisableComparator(new IdParser).compare("a", "b"))
然后:
错误:类型不匹配; 找到 : (this.Parser#Result, this.Parser#Result) => 布尔值 必需:(this.IdParser#Result, this.IdParser#Result) => 布尔值 涉及默认参数的应用程序发生错误。 println(new CustomisableComparator(new IdParser).compare("a", "b")) ^哦,好吧,我希望CustomisableComparator 中的类型变量P 绑定到IdParser,所以我不太清楚为什么scala 认为它的默认值是Parser。让我们忘记默认值并明确提供值:
println(new CustomisableComparator(new IdParser, (r1: IdParser#Result, r2: IdParser#Result) => r1 == r2).compare("a", "b"))
错误:类型不匹配;
找到 : (this.IdParser#Result, this.IdParser#Result) => 布尔值
必需: (?#Result, ?#Result) => 布尔值
println(new CustomisableComparator(new IdParser, (r1: IdParser#Result, r2: IdParser#Result) => r1 == r2).compare("a", "b"))
^
这很令人困惑。如果我不提供值,编译器需要(this.IdParser#Result, this.IdParser#Result) => Boolean;一旦我确实提供了这种类型的值,它就需要(?#Result, ?#Result) => Boolean。谁能解释这里发生了什么?
【问题讨论】:
标签: scala