【发布时间】:2011-03-11 15:42:40
【问题描述】:
我正在尝试使一个序列(例如,其他集合类型也可以)与其他序列具有可比性。
class RichSeq[A](val seq: Seq[A]) extends Ordered[RichSeq[A]]
当然在引用的包对象中有隐式转换:
implicit def seq2RichSeq[A](s: Seq[A]) = new RichSeq(s)
比较意味着,第一个尺寸比每个元素都重要。代码很清楚:
class RichSeq[A](val seq: Seq[A]) extends Ordered[RichSeq[A]] {
def compare(s: RichSeq[A]) = {
seq.size compare s.seq.size match {
case 0 => seq.view.zip(s.seq).map { case (x,y) => ord.compare(x,y) }.dropWhile(_ == 0).headOption.getOrElse(0)
case x => x
}
}
}
但这并不能编译(当然),因为需要一个排序来比较元素,所以我尝试了:
class RichSeq[A](val seq: Seq[A]) extends Ordered[RichSeq[A]] {
def compare(s: RichSeq[A])(implicit ord: Ordering[A]) = {
// ...
}
}
现在 compare 方法的签名不合适,所以我将隐式 ord 移到类签名中(并适应了隐式转换):
implicit def seq2RichSeq[A](s: Seq[A])(implicit ord: Ordering[A]) = new RichSeq(s)
class RichSeq[A](val seq: Seq[A])(implicit ord: Ordering[A]) extends Ordered[RichSeq[A]] {
def compare(s: RichSeq[A]) = {
// ...
}
}
但现在我有一个问题,我想通过implicit 在Seq[A] 上使用RichSeq 中的所有其他方法也需要一个隐式Ordering[A],我不能总是提供一个。有时我使用我的RichSeq by 方法而不使用 Ordering,有时使用 compare 方法。
例如,有时我会调用
def distinctBy[B](f: A => B): Seq[A] = {
seq.foldLeft { (Buffer[A](),MutMap[B,A]()) } {
case ((b,m),x) if m contains f(x) => (b,m)
case ((b,m),x) =>
m += f(x) -> x
b += x
(b,m)
}._1
}
同时我无法定义Ordering[A]。
我看到一个解决方案是拥有两个不同的类(有两个隐式转换):
class RichSeqOrderable[A](val seq: Seq[A])(implicit ord: Ordering[A]) extends Ordered[RichSeqOrderable[A]]
class RichSeq[A](val seq: Seq[A])
但我认为这打破了将所有东西放在一起的想法?!?
【问题讨论】:
-
我会去上两节课,但在同一个文件中。
标签: scala