我正在尝试解决缺少collection.mutable.SortedSet
这个我的跳过列表实现的问题。我快到了:
import collection.{SortedSet => CSortedSet, SortedSetLike => CSortedSetLike}
import collection.mutable.{Set => MSet, SetLike => MSetLike}
import collection.generic.{MutableSetFactory, GenericCompanion}
object SkipList extends MutableSetFactory[SkipList] {
def empty[A](implicit ord: Ordering[A]): SkipList[A] = ???
}
trait SkipList[A] extends MSet[A] with MSetLike[A, SkipList[A]] with CSortedSet[A]
with CSortedSetLike[A, SkipList[A]] {
override def empty: SkipList[A] = SkipList.empty[A](ordering)
def rangeImpl(from: Option[A], until: Option[A]): SkipList[A] =
throw new Exception("Unsupported operation")
}
好的,这个编译。但与不可变的排序集不同,我可以毫不含糊地做
case class Holder(i: Int) extends Ordered[Holder] {
def compare(b: Holder) = i.compare(b.i)
}
def test1(iss: ISortedSet[Holder]) = iss.map(_.i)
test1(ISortedSet(Holder(4), Holder(77), Holder(-2))).toList
我的可变排序集失败了:
def test2(sl: SkipList[Holder]) = sl.map(_.i)
与
error: ambiguous implicit values:
both method canBuildFrom in object SortedSet of type [A](implicit ord: Ordering[A])scala.collection.generic.CanBuildFrom[scala.collection.SortedSet.Coll,A,scala.collection.SortedSet[A]]
and method canBuildFrom in object Set of type [A]=> scala.collection.generic.CanBuildFrom[scala.collection.mutable.Set.Coll,A,scala.collection.mutable.Set[A]]
match expected type scala.collection.generic.CanBuildFrom[SkipList[Holder],Int,That]
def test2( sl: SkipList[ Holder ]) = sl.map( _.i )
^
这超出了我的概述。有关如何实现不可变排序集已经完成的任何线索?我有机会消除这种歧义吗?
答案 0 :(得分:7)
您似乎需要在对象canBuildFrom
中定义SkipList
方法。虽然不需要这样做,但定义自己的canBuildFrom
的目的是确保继承的方法返回最佳类型。由于您混合了几个特征,如果您没有定义自己的隐式canBuildFrom
,则会产生歧义。
在您的情况下,添加类似
的内容import collection.generic.{CanBuildFrom, MutableSetFactory}
import collection.mutable.{Set, SetLike}
object SkipList extends MutableSetFactory[SkipList] {
implicit def canBuildFrom[A : Ordering]: CanBuildFrom[Coll, A, SkipList[A]] =
new CanBuildFrom[Coll, A, SkipList[A]] {
def apply(from: Coll) = newBuilder[A]
def apply() = newBuilder[A]
}
}
trait SkipList[A]
extends Set[A] with SetLike[A, SkipList[A]] {
override def empty: SkipList[A] = SkipList.empty[A]
}
应该这样做。
几个月前,Martin写了一篇关于在The Architecture of Scala Collections中实现自定义集合的文档,其中包含section on integrating new sets and maps。虽然它非常难以找到,但如果您对构建自己的馆藏感兴趣,它将是一个权威资源。答案 1 :(得分:2)
使用适当的implicit def canBuildFrom
是可能的。我现在从SortedSet
删除了任何mixins,因为我的实际实现不仅需要Ordering
,还需要另一个证据参数。所以我从SortedSet
重新添加了一些位。解决方案是:
import collection.generic.CanBuildFrom
import collection.mutable.{Builder, Set => MSet, SetBuilder => MSetBuilder,
SetLike => MSetLike}
object SkipList {
def empty[A](implicit ord: Ordering[A]): SkipList[A] = ???
private type CC[A] = SkipList[A]
private type Coll = CC[_]
implicit def canBuildFrom[A: Ordering]: CanBuildFrom[Coll, A, CC[A]] =
new SkipListCanBuildFrom
private class SkipListCanBuildFrom[A: Ordering]
extends CanBuildFrom[Coll, A, CC[A]] {
def apply(from: Coll) = newBuilder[A]
def apply() = newBuilder[A]
}
def newBuilder[A: Ordering]: Builder[A, CC[A]] = new MSetBuilder(empty[A])
}
trait SkipList[A] extends MSet[A] with MSetLike[A, SkipList[A]] {
override def empty: SkipList[A] = SkipList.empty[A](ordering)
implicit def ordering: Ordering[A]
}
测试编译(并在实际实现中工作,为简洁起见,此处省略):
case class Holder(i: Int)
def test2(sl: SkipList[Holder]): SkipList[Int] = sl.map(_.i + 1)