scala:使用F-Bound参数引用Trait

时间:2015-04-20 14:22:05

标签: scala parametric-polymorphism

我正在设计一个F-Bound数据类型,并且有一个工作的伴侣对象。我想从特质本身引用这个伴侣对象,但我无法使这些类型正确。

trait A[AA <: A[AA]] {
  self =>
  val data: String
}
case class A1(data : String) extends A[A1]

trait B[BB <: B[BB, AA], AA <: A[AA]] {
  self: BB =>
  val content: AA
  def companion: BComp[BB, AA]  // What is the correct type?
  def companion2: BComp2[BB, AA] // What is the correct type?
}
trait BComp[BB[X <: BB[X, AA], Y <: AA[Y]], AA[Y <: AA[Y]]]

trait BComp2[BB[X <: AA[X]], AA[X <: AA[X]]]

case class BInst[AA <: A[AA]](content: AA) extends B[BInst[AA], AA] {
  def companion = BInst
  def companion2 = BInst2
}

object BInst extends BComp[B, A]
object BInst2 extends BComp2[BInst, A]

companioncompanion2的工作解决方案就足够了,尽管有关如何构建这些类型签名的一般提示会很有用。

修改

我想使用伴侣对象来存储canBuildFrom样式含义以及构建器,但由于内容类型A有上限,所有生成函数都需要知道这个边界,因此伴随对象特征的参数化。这个设计的灵感来自GenericCompanion.scala,当然,添加类型边界会使一切变得更加困难:P

1 个答案:

答案 0 :(得分:0)

companion类型的任何明确定义的障碍是BComp由两个参数化类型参数化 - 而第一个与B兼容,第二个AA[Y <: AA[Y]]是不可能构建的。很简单,我们需要将此类型添加到B

的参数化中
trait B[BB <: B[BB, AA, X],
        AA[T <: AA[T]] <: A[T], 
        X <: AA[X]]  {
    self: BB =>
    val content: X
    def companion: BComp[B, AA]
}

现在我们的伴随对象(只需要很小的扩展)就可以使用兼容类型AA

trait BComp[BHere[BB <: BHere[BB, AAA, Z],
                  AAA[Y <: AAA[Y]],
                  Z <: AAA[Z]],
            AA[Y <: AA[Y]]]

不是很漂亮吗?

case class BInst[X <: A[X]](content: X) extends B[BInst[X], A, X] {
    def companion: BComp[B, A] = BInst5
  }
object BInst extends BComp[B, A]

<强> companion2

对于companion2,我们只需要更改B参数化的第一部分,以便特质B和伴随特征变为:

trait B[BB[TS <: AA[TS]] <: B[BB, AA, TS],
        AA[T <: AA[T]] <: A[T], 
        X <: AA[X]] {
    self: BB[X] =>
    val content: X
    def companion2: BComp[BB, AA]
  }

trait BComp[BHere[TS <: AA[TS]],
            AA[Y <: AA[Y]]]

这稍微易于管理。案例类和案例对象是:

case class BInst[X <: A[X]](content: X) extends B[BInst, A, X] {
  def companion2: BComp[BInst, A] = BInst5
}
object BInst extends BComp[BInst, A]

如果这对任何人都有用,那就重新思考一下。我改变了自己的设计方法,我建议你也这样做。提出这些类型的解决方案现在已经是纯粹的学术练习!