Do you really need a generic parameter A
, or was that just for example sake? If you had a concrete type instead of A
, then you could just create an instance that mixes in both traits:
trait Duck {
def walk: Unit
}
trait Goose {
def run: Unit
}
def learnToDuckWalk: Goose with Duck = new Goose with Duck {
def run = println("tip tap top")
def walk = println("flic flak floc")
}
learnToDuckWalk.walk
learnToDuckWalk.run
However, having a generic A
and "bolting-on" some extra traits is not really a good design, even if you managed to implement it (e.g. using reflection).
A better approach would be, instead of saying "I have an A
that is mixed in with Duck
", to say "I have an A
that has a Duck
type class instance".
trait Duck [A]{
def walk : Unit
}
object Duck {
implicit val duckString = new Duck[String] {
def walk = print("Stringy flic flak floc")
}
implicit val duckInt = new Duck[Int] {
def walk = print("Inty flic flak floc")
}
...
implicit def duckA[A] = new Duck[A] {
def walk = print("Generic flic flak floc")
}
}
This way you can provide type class instances for any type you want, and you can have them behave differently depending on the actual type (see how walk
prints a different message fo each type).
Then your use-site can look like this:
import Duck._
def learnToDuckWalk[A : Duck](a : A) = {
val aDuck = implicitly[Duck[A]]
aDuck.walk // prints Stringy flic flak floc
}
learnToDuckWalk("Some string")
Important part here is the [A : Duck]
type, which means "any A
for which a Duck
type class instance exists".