Scala 如何抽象地扩展一个路径依赖的特征:“;超越特质;?

Scala 如何抽象地扩展一个路径依赖的特征:“;超越特质;?,scala,overriding,traits,path-dependent-type,Scala,Overriding,Traits,Path Dependent Type,对于路径依赖特性,如何为特定的封闭对象指定该特性必须支持其他特性覆盖特性?你是如何引用这个子序列延伸的原始特征的 具体来说,我想覆盖每个DeltaSet对象中的Delta特征: trait DeltaSet { type PertainsTo trait Delta { val pertainsTo: PertainsTo } . . . } 在英语中,这是“同一DeltaSet中的每个Delta都必须属于同一类事物。” DeltaSet对象应该能够向Delta特征添

对于路径依赖特性,如何为特定的封闭对象指定该特性必须支持其他特性<代码>覆盖特性?你是如何引用这个子序列延伸的原始特征的

具体来说,我想覆盖每个
DeltaSet
对象中的
Delta
特征:

trait DeltaSet {
  type PertainsTo

  trait Delta {
    val pertainsTo: PertainsTo
  }
  . . .
}
在英语中,这是“同一
DeltaSet
中的每个
Delta
都必须属于同一类事物。”

DeltaSet
对象应该能够向
Delta
特征添加更多属性,如
source
此处:

val deltaSet = new DeltaSet {
  override type PertainsTo = UnorderedPair[TestNode]

  override trait Delta /* extends DeltaSet.Delta?? */ {  // <-- THE MYSTERY
    val source: TestNode
  }
  . . .
}
对于
BreakLinkDelta
和其他
delta
而言,对于
deltaSet
也是如此。(此
Delta集的每个
Delta
描述了对图形所做的更改。其他
Delta集包含对完全不同类型对象的更改。)


我尝试了很多变体,包括
trait BaseDelta{…};键入DeltaTExtend
DeltaSet
及其
Delta
添加
source
属性:

trait DeltaSetTN extends DeltaSet {
  override type PertainsTo = UnorderedPair[TestNode]
  trait DeltaTN extends Delta {
    val source: TestNode
  }
}
然后:

您可能会对Scala中的依赖项注入和cake模式感兴趣。

这可以:

(1) 在封闭的trait中定义一个base
trait
,并将其作为抽象
类型的上限

(2) 使用
object
语句而不是
val
语句创建容器对象

(3) 在
对象
上放置一个类重写,用与抽象
类型
相同的名称定义封闭的
特征
。此定义必须扩展基本的
trait
,并且不能有
override
关键字


下面是(1),封闭的特征:

trait DeltaSet {
  type PertainsTo

  trait BaseDelta {
    val pertainsTo: PertainsTo
  }

  type Delta <: BaseDelta          // <-- Since this is now a type, we can override it...
  . . .
}
我猜
object
编译失败和
val
失败的原因是
val
没有定义名称空间,我们需要一个名称空间来引用封闭的、被覆盖的
Delta
特征,当我们在这里将其子类化时:

case class MakeLinkDelta(fromNode: TestNode, toNode: TestNode)
  extends deltaSet.Delta           // Since deltaSet is a namespace, the dot syntax can refer
{                                  // to the Delta trait inside it.
  override val pertainsTo = new UnorderedPair(fromNode, toNode)
  override val source = fromNode
  . . .
}

(最后一部分与问题中的代码相同。)

您能在此解释相关的工作原理吗?“不能在匿名类中重写路径依赖特征”?“你不能在任何地方覆盖路径依赖特征”?“每个路径相关(
Delta
)对象必须扩展容器(
DeltaSet
)特性”?我希望最后一个不是真正的原则。我们不能忽略一个特征。为此,我们扩展并覆盖其成员。我不太明白你的最后一点。一个特征在实例化时不能保持为一个特征。谢谢你的“我们不能覆盖一个特征。”(也许这可以作为答案。)澄清最后一点:在您的解决方案中,
Delta
类扩展了
DeltaSet
的特性。这对我来说似乎很奇怪,就像说杯子是一种橱柜。有什么Scala原则需要这样做吗?我将把问题中的
MakeLinkDelta
改为
DeltaForLink
,因为“Make”可能会引起混淆。非常好。:)我想我会切换回
MakeLinkDelta
,并提到一个对比鲜明的
BreakLinkDelta
。这应该可以澄清,对于一个
DeltaSet
,可以有许多
Delta
类(并且需要较少的编辑)。
trait DeltaSet {
  type PertainsTo

  trait BaseDelta {
    val pertainsTo: PertainsTo
  }

  type Delta <: BaseDelta          // <-- Since this is now a type, we can override it...
  . . .
}
object deltaSet extends DeltaSet {
  override type PertainsTo = UnorderedPair[TestNode]

  trait Delta extends BaseDelta {  // ...except we don't override, we just define a trait
    val source: TestNode           // with the same name as the abstract type.
  }
  . . .
}
case class MakeLinkDelta(fromNode: TestNode, toNode: TestNode)
  extends deltaSet.Delta           // Since deltaSet is a namespace, the dot syntax can refer
{                                  // to the Delta trait inside it.
  override val pertainsTo = new UnorderedPair(fromNode, toNode)
  override val source = fromNode
  . . .
}