Following from this question, I have now the following:
case class Pet(val name: String)
trait ConfigComponent {
What you've written should work, but doesn't, because of this bug.
There are a number of workarounds you could use. Adding type Config = PetStoreConfig with AnotherConfig
to your module implementation is probably a little less unpleasant than casting.
Update: As som-snytt notes in a comment and answer, adding with PetStoreModuleImpl
(crucially not with PetStoreModule
, as you might expect) to the end of the self-type is a better solution.
As a footnote: as discussed in the comments on SI-7255, the Dependent Object Types calculus (which is designed to be "a new foundation for Scala's type system") will address this "fundamental problem in Scala's type system".
You can wrangle your self-type to keep the abstract type member you want, since the last bound wins:
trait PetStoreModuleImpl extends PetStoreModule {
self: VetModule with AnotherModule with PetStoreModuleImpl =>
override def petStore: PetStore = PetstoreImpl
object PetstoreImpl extends PetStore {
def sell(pet: Pet) {
vet.vaccinate(pet)
println(s"Sold $pet! [Store: ${config.petStoreName}, lastName: $getLastName]")
}
}
}
Then it will tell you that the vet module isn't configured:
class MyApp extends PetStoreModuleImpl with VetModuleImpl with AnotherModuleImpl {
override type Config = PetStoreConfig with VetModuleConfig with AnotherConfig
override object config extends PetStoreConfig with VetModuleConfig with AnotherConfig {
val petStoreName = "MyPetStore"
val lastName = "MyLastName"
val extra = "vet-info"
}
petStore.sell(new Pet("Fido"))
}