2

There are countless questions on this topic and a quite good, if not very precisely worded article here: Revisiting implicits without the import tax. I've read most of them, but have a problem with overriding default CanBuildFrom implicits without repeating the declarations myself. If you're familiar with scala collection library and resolution of CanBuildFrom, you know that for every scala collection trait CC[X], its companion object defines an implicit CanBuildFrom[CC[_], X, CC[X]] instance. I have introduced my own collection hierarchy, rooted in a class derived from IndexedSeq[X]:

trait SpecSeq[X] extends IndexedSeq[X]
trait MutableSeq[X] extends SpecSeq[X]
trait ConstSeq[X] extends SpecSeq[X]
trait ArraySeq[X] extends MutableSeq[X]
trait ConstArray[X] extends ConstSeq[X]

Can I avoid declaring implicit values in companion objects of all defined traits and instead extract them to a common base trait for the companion objects? I tried having:

trait SpecCompanion[S[X]<:SpecSeq[X]] {
    implicit def canBuildFrom[X] :CanBuildFrom[S[_], X, S[X]] = ???
}
ArraySeq extends SpecCompanion[ArraySeq]
ConstArray extends SpecCompanion[ConstArray]
...

Unfortunately, those definitions aren't considered more specific than the one declared in object IndexedSeq. This issue is aggreviated by the fact that in reality it's not a single implicit value, but several with increasing level of requirements for X.

4

1 に答える 1

0

私は間接的な層と私自身のサブクラスになりましたCanBuildFrom

trait SpecCanBuildFrom[-F, -E, +T] extends CanBuildFrom[F, E, T]

trait SpecCompanion[S[X]<:SpecSeqw[X]] {
    implicit def cbf[X] :SpecCanBuildFrom[S[_], X, S[S]] = ???
}

object SpecSeq extends SpecCompanion[SpecSeq] {
    implicit def canBuildFrom[C[X]<:SpecSeq[X], X](implicit ev :SpecCanBuildFrom[C[_], X, C[X]) :CanBuildFrom[C[_], X, C[X]] = ev
}

object ArraySeq extends SpecCompanion[ArraySeq]
object ConstArray extends SpecCompanion[ConstArray]

現在、SpecSeq のジェネリック定義は、scala コレクションのすべての暗黙をオーバーライドします。

十分ですが、直接行うことが可能かどうか疑問に思います。

于 2016-06-20T10:54:39.313 に答える