Scala:强制在特征

时间:2016-06-19 18:17:34

标签: scala scala-collections scala-implicits

关于这个主题有无数的问题,这里有一篇非常好的,如果不是非常精确的措辞:Revisiting implicits without the import tax。我已经阅读了大部分内容,但在覆盖默认CanBuildFrom含义时遇到问题,而不自行重复声明。如果您熟悉scala集合库和CanBuildFrom的解析,则您知道对于每个scala集合特征CC[X],其伴随对象定义了一个隐式CanBuildFrom[CC[_], X, CC[X]]实例。我已经介绍了我自己的集合层次结构,它源于一个派生自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]

我可以避免在所有已定义特征的伴随对象中声明隐含值,而是将它们提取到伴随对象的公共基本特征吗? 我试过:

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

不幸的是,这些定义并不比object IndexedSeq中声明的定义更具体。这个问题受到这样的事实的影响:实际上它并不是一个隐含的价值,而是一些X的要求水平越来越高。

1 个答案:

答案 0 :(得分: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集合中的所有含义。

足够好,但我想知道是否可以直接这样做。