Skip to content

Instantly share code, notes, and snippets.

@dvic
Created August 20, 2013 08:42
Show Gist options
  • Save dvic/6278827 to your computer and use it in GitHub Desktop.
Save dvic/6278827 to your computer and use it in GitHub Desktop.
Scala cake pattern with Existential Types: compile error
case class Pet(val name: String)
trait ConfigComponent {
type Config
def config: Config
}
trait VetModule extends ConfigComponent {
type Config <: VetModuleConfig
def vet: Vet
trait Vet {
def vaccinate(pet: Pet)
}
trait VetModuleConfig {
def extra: String
}
}
trait VetModuleImpl extends VetModule {
override def vet: Vet = VetImpl
object VetImpl extends Vet {
def vaccinate(pet: Pet) = println("Vaccinate:" + pet + " " + config.extra)
}
}
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 PetStoreModule extends ConfigComponent {
type Config <: PetStoreConfig
def petStore: PetStore
trait PetStore {
def sell(pet: Pet): Unit
}
trait PetStoreConfig {
val petStoreName: String
}
}
trait PetStoreModuleImpl extends PetStoreModule {
self: VetModule with AnotherModule =>
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]")
}
}
}
class MyApp extends PetStoreModuleImpl with VetModuleImpl with AnotherModuleImpl {
type Config = PetStoreConfig with AnotherConfig
override object config extends PetStoreConfig with AnotherConfig {
val petStoreName = "MyPetStore"
val lastName = "MyLastName"
}
petStore.sell(new Pet("Fido"))
}
object Main {
def main(args: Array[String]) {
new MyApp
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment