【问题标题】:Scala: enforcing precedence of an implicit declared in a traitScala:强制在特征中声明的隐式优先级
【发布时间】:2016-10-20 23:48:25
【问题描述】:

关于这个主题有无数的问题,如果不是非常精确的话,这里有一篇相当不错的文章:Revisiting implicits without the import tax。我已经阅读了其中的大部分内容,但是在不重复声明的情况下覆盖默认 CanBuildFrom 存在问题。如果您熟悉 scala 集合库和 CanBuildFrom 的解析,您就会知道对于每个 scala 集合 trait 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 的要求越来越高,这个问题更加严重。

【问题讨论】:

    标签: scala scala-collections scala-implicits


    【解决方案1】:

    我最终得到了一个间接层和我自己的子类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 集合中的所有隐式。

    够了,不过不知道能不能直接做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 2016-08-24
      • 2013-08-03
      相关资源
      最近更新 更多