Skip to content

Instantly share code, notes, and snippets.

@kailuowang
Created December 21, 2015 22:34
Show Gist options
  • Save kailuowang/6f8350a4a9d0bbfc45ee to your computer and use it in GitHub Desktop.
Save kailuowang/6f8350a4a9d0bbfc45ee to your computer and use it in GitHub Desktop.
Abstract Type vs Type parameter
trait AnimalMouth
class Beak extends AnimalMouth
//================================Generic type works as in the following =======================
trait Animal[Mouth <: AnimalMouth] {
def mouth : Mouth
def feedAnother(m: Mouth): Unit = ()
}
class Bird extends Animal[Beak] {
def mouth: Beak = new Beak
}
object Test{
def feed[Mouth <: AnimalMouth, A <: Animal[Mouth]](mother: A, child: A) : Unit = mother.feedAnother(child.mouth)
}
//==============Make mouth an abstract type and it would be hard ===========================
trait Animal {
type Mouth <: AnimalMouth
def mouth : Mouth
def feedAnother(m: Mouth): Unit = ()
}
class Bird extends Animal {
type Mouth = Beak
def mouth: Mouth = new Beak
}
object Test{
def feed[A <: Animal](mother: A, child: A) : Unit = mother.feedAnother(child.mouth) //won't compile, no way to write something like this?
}
//=============== Work Around using Aux ================
trait Animal {
type Mouth <: AnimalMouth
def mouth : Mouth
def feedAnother(m: Mouth): Unit = ()
}
object Animal {
type Aux[Mouth0] = Animal { type Mouth = Mouth0 }
}
object MotherFeed {
def feed[Mouth](mother: Animal.Aux[Mouth], child: Animal.Aux[Mouth]) : Unit = mother feedAnother child.mouth
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment