存在类型 : compile error 的 Scala 蛋糕模式

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

通过this问题,我找到了this Precog 关于“配置”模式的文章。我用两个模块尝试了这个:

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
  }
}

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

overriding type Config in trait AnotherModule with bounds <: MyApp.this.AnotherConfig;
type Config has incompatible type
type Config = PetStoreConfig with AnotherConfig



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

最佳答案

您定义了 AnotherConfig 两次——一次在 AnotherModule 中,一次在 AnotherModuleImpl 中。这两个特征的定义是不同的,被认为是不相容的。 Config 类型是根据前者定义的,但是当您定义 MyApp 时,您将类型设置为后者 - 因此会出现错误。

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

关于存在类型 : compile error 的 Scala 蛋糕模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18330042/

相关文章:

c++ - C++ 概念是存在类型的一种形式吗?

java - 使用 Java 通配符

java - 在不使用具有长参数列表的构造函数的情况下构建大的、不可变的对象

scala - 使用 Apache-Spark 进行迭代计算时出现 StackOverflowError

assembly - 编译简单的SPARC ASM数学代码时出错

java - Sun JRE javac 和 Eclipse java 编译器之间的不一致?

haskell - 如何使用函数依赖和存在量化来为我的类型删除不必要的参数

java - 向 Scala Swing Panel 添加标签时出现类型不匹配错误

scala - 模式匹配时如何摆脱 "unchecked due to erasure"警告

objective-c - Xcode7.3.1-链接器命令失败,退出代码为1