我们定义了自定义Equality[String]
:
implicit val upperCaseEquality = new Equality[String] {
override def areEqual(self: String, b: Any): Boolean = b match {
case other: String => self.toUpperCase == other.toUpperCase
case _ => false
}
}
以下代码正常运行:
Seq("a").view should contain theSameElementsInOrderAs Seq("A")
现在,我们为Equality
添加了自定义Seq
:
implicit def SeqEquality[T, SEQ[e] <: GenSeq[e]](implicit equality: Equality[T]): Equality[SEQ[T]] = new Equality[SEQ[T]] {
override def areEqual(self: SEQ[T], b: Any): Boolean = b match {
case other: GenSeq[_] => self.size == other.size && self.zip(other).forall(equality.areEqual _ tupled)
case _ => false
}
}
自定义TripleEquals
平等适用于Seq
:
assert(Seq("a") === Seq("A"))
但不适用于SeqView
:
assert(Seq("a").view === Seq("A"))
Exception in thread "main" org.scalatest.exceptions.TestFailedException: SeqView("a") did not equal List("A")
为什么?
答案 0 :(得分:1)
如果你看what .view
returns:
def view(from: Int, until: Int): SeqView[A, Seq[A]]
您发现SeqView[_, _]
实际上有两个类型参数,因此它不符合您的规范SEQ[e] <: GenSeq[e]
。 (理论上你可以想象,如果Scala支持部分应用的类型构造函数,这可能会以某种方式统一,但这是一个棘手的问题而Scala不支持它。)
在您的情况下,您可以通过为SeqView
明确定义并且不使用更高级别的类型来使其工作:
implicit def SeqViewEquality[T](implicit equality: Equality[T]): Equality[SeqView[T, Seq[T]]] = new Equality[SeqView[T, Seq[T]]] {
override def areEqual(self: SeqView[T, Seq[T]], b: Any): Boolean = b match {
case other: GenSeq[_] => self.size == other.size && self.zip(other).forall(equality.areEqual _ tupled)
case _ => false
}
}
虽然,我承认这有点令人不满意。