Scala通用自我类型不匹配

时间:2013-03-24 20:58:55

标签: scala generics self-type

我正在尝试将Scala的蛋糕模式与具有多个组(层)的通用拦截器一起使用。当一个层的结尾需要另一个层时,我尝试用自我类型来表达。但它失败了非法继承。这个任务的一般背景是我有一个文档模型,我正在尝试进行验证链。玩具示例如下,每个图层仅由一个特征表示。

trait Element
trait Leaf extends Element
trait Composed extends Element

trait Validator [A] {def validate (element : A) : String}

//second layer
trait LeafValidator extends Validator[Leaf]{
  override def validate (element : Leaf) : String = "leaf"}

//first layer
trait ElementValidator extends Validator[Element]{
  self : Validator[Leaf] =>

  override def validate (element : Element) : String = element match {
    case leaf : Leaf => super.validate(leaf)
    case _ => "other"
  }
}

case class Concrete extends LeafValidator with ElementValidator

错误发生在实例化行

  

非法继承; self-type apltauer.david.util.Concrete不符合apltauer.david.util.ElementValidator的selftype apltauer.david.util.ElementValidator和apltauer.david.util.Validator [apltauer.david.util.Leaf] Main.scala /依赖/ src / apltauer / david / util行56 Scala问题

逆变法抑制了错误,但没有解决问题,因为自我类型无用。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。使用两种特征变形打破了(否则,漂亮和有用)蛋糕模式。

所以我开发了一个增强功能,就我的问题而言,它允许我保持蛋糕图案完好无损,我称之为特征模式。在你的情况下:

trait element_validator extends validator[Element] {
   final override val element_validator = this
}
trait feature_element_validator { val element_validator : element_validator }

/* Analogous for “Leaf” */

trait validator[element_type] {
   final override val validator = this
   /* Feature code here: */
   def validate(element: element_type) = /* … */
}
trait feature_validator[element_type] { val validator : validator[element_type] }

所以现在可以说:

object component
   extends element_validator
   with leaf_validator
   with other_cake_feature_1
   with other_cake_feature_2
   with other_cake_feature_3
   /* etc. */

内部组件可以区分两种验证器:

element_validator.validate(…)
leaf_validator.validate(…)

如果只有一个需要,则导入(与使用自我类型注释获得名称的效果相同):

import element_validator._
validate(…)

我知道,这是一些样板。然而,我没有看到任何其他解决方案,而不是将蛋糕与成分结合起来(无论何时需要组合物)。