存在类型的Scala蛋糕模式:编译错误

时间:2013-08-20 08:11:16

标签: scala compiler-errors existential-type cake-pattern

通过this问题,我在Precog的'config'模式中找到了this文章。我尝试了两个模块:

case class Pet(val name: String)

trait ConfigComponent {
  type Config

  def config: Config
}

trait Vet {
  def vaccinate(pet: Pet) = {
    println("Vaccinate:" + pet)
  }
}


trait AnotherModule extends ConfigComponent {
  type Config <: AnotherConfig

  def getLastName(): String

  trait AnotherConfig {
    val lastName: String
  }

}

trait AnotherModuleImpl extends AnotherModule {
  override def getLastName(): String = config.lastName

  trait AnotherConfig {
    val lastName: String
  }

}

trait PetStoreModule extends ConfigComponent {
  type Config <: PetStoreConfig

  def sell(pet: Pet): Unit

  trait PetStoreConfig {
    val vet: Vet
    val name: String
  }

}

trait PetStoreModuleImpl extends PetStoreModule {
  override def sell(pet: Pet) {
    println(config.name)
    config.vet.vaccinate(pet)
    // do some other stuff
  }
}

class MyApp extends PetStoreModuleImpl with AnotherModuleImpl {

  type Config = PetStoreConfig with AnotherConfig

  override object config extends PetStoreConfig with AnotherConfig {
    val vet = new Vet {}
    val name = "MyPetStore"
    val lastName = "MyLastName"
  }

  sell(new Pet("Fido"))
}


object Main {
  def main(args: Array[String]) {
    new MyApp
  }
}

但是,我得到这个编译错误:

  

覆盖类型Config in trait AnotherModule with bounds&lt ;: MyApp.this.AnotherConfig;
  类型Config具有不兼容的类型
  使用AnotherConfig键入Config = PetStoreConfig

我不清楚为什么这不起作用(Precog在他们的例子中也使用了两个组件),任何想法?

2 个答案:

答案 0 :(得分:1)

你定义了AnotherConfig两次 - 一次在AnotherModule中,一次又在AnotherModuleImpl中。这两种性状的定义是不同的,被认为是不相容的。类型Config是根据前者定义的,但是当您定义MyApp时,您将类型设置为后者 - 因此错误。

您可以通过删除AnotherConfig的后一个定义(由@rar建议)或后一个特征扩展前者(如果您有理由保留后者,例如定义额外字段)来修复它。

答案 1 :(得分:0)

从AnotherModuleImpl中删除AnotherConfig的定义