1
的斯卡拉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"))
它产生如预期的那样,虚假。不幸的是,它从这里下坡。为了允许发烧友对比,我定义:
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"))
但后来:
error: type mismatch; found : (this.Parser#Result, this.Parser#Result) => Boolean required: (this.IdParser#Result, this.IdParser#Result) => Boolean Error occurred in an application involving default arguments. 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"))
error: type mismatch; found : (this.IdParser#Result, this.IdParser#Result) => Boolean required: (?#Result, ?#Result) => Boolean 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
。任何人都可以解释这里发生了什么?
感谢您的解决方案。我仍然困惑于为什么当使用默认和显式参数时“required”类型不同。第一个“必需”表明编译器能够正确推断函数的类型。在第二种情况下,它突然失去了这种能力。 我对于推理者应该能做什么的期望是通过对Haskell的短暂暴露而设定的。它似乎始终能够至少尽可能地推断出,并且通常更多。在这种情况下,推论对我来说显得很明显,所以我希望scalac也能找出答案。 – 2011-05-08 09:14:56