更新双F-Bound多态类型的函数

时间:2015-04-15 16:34:58

标签: scala parametric-polymorphism self-type

我希望能够在参数化的F-Bounded特性中提供更新后复制功能,其中B更新的值也是F-Bounded。特征如下:

sealed trait A[AA <: A[AA]] {
  self: AA =>
  val data: String
}

sealed trait B[BB <: B[BB, AA], AA <: A[AA]] {
  self: BB =>
  val content: AA
}

case class BInst[BB <: B[BB,AA], AA <: A[AA]](content: AA) extends 
     B[BInst[BB, AA], AA]

在特质B中,我想提供一个带签名的函数

def update[NewA <: AA](newA: NewA) : BB[BB, NewA]

以便case类只实现

def update[NewA <: AA](newA: NewA) = copy(content = newA)

但目前还没有编译。 updateB的正确类型是什么?

修改

应该有效的例子(但目前还没有):

  class A2Inst extends A[A2Inst] { val data: String = "A2Inst" }
  class A2Inst2 extends A2Inst {override val data: String = "A2INst2" }
  val a1 = new A2Inst
  val a2 = new A2Inst2
  val b = BInst(a1)
  b.update(a2)

1 个答案:

答案 0 :(得分:0)

BB不接受类型参数,只需删除它们并更正输入和返回类型:

sealed trait A[AA <: A[AA]] {
  self: AA =>
  val data: String
}

sealed trait B[BB <: B[BB, AA], AA <: A[AA]] {
  self: BB =>
  def update[NewA <:A[NewA]](newA: NewA) : B[_, NewA]
  val content: AA
}

case class BInst[BB <: B[BB,AA], AA <: A[AA]](content: AA) extends 
     B[BInst[BB, AA], AA] {
  def update[NewA <: A[NewA]](newA: NewA) = copy(content = newA)
}
defined trait A
defined trait B
defined class BInst

NewA <:A[NewA]应作为输入传递以符合AA <: A[AA]。使用新的BB返回相同的NewA是不可能的,因此您的方法会返回其他BB

您的edit1更新:A2Inst2不是F-bounded,因此您甚至不能BInst(a1),所以您应该:

class A2InstBase[T <: A2InstBase[T]] extends A[T] {val data = "a2Inst"}
class A2Inst extends A2InstBase[A2Inst]
class A2Inst2 extends A2InstBase[A2Inst2]{override val data = "a2Inst2"}