问题
Through this question, I found this article on the 'config' pattern from Precog. I tried this with two modules:
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
}
}
However, I get this compile errror:
overriding type Config in trait AnotherModule with bounds <: MyApp.this.AnotherConfig;
type Config has incompatible type
type Config = PetStoreConfig with AnotherConfig
It is not clear to me why this should not work (Precog also uses two components in their example), any ideas?
回答1:
Remove definition of AnotherConfig from AnotherModuleImpl
回答2:
You define AnotherConfig twice - once in AnotherModule, and again in AnotherModuleImpl. These two definitions of the trait are different, and are considered incompatible. The type Config is defined in terms of the former of these, but when you define MyApp, you are setting the type to the latter - hence the error.
You can fix it by either removing the latter definition of AnotherConfig (as suggested by @rarry) or having the latter trait extend the former (if you have some reason to keep the latter, such as defining extra fields).
来源:https://stackoverflow.com/questions/18330042/scala-cake-pattern-with-existential-types-compile-error