Let’s say I have a class with a type parameter and a method that should return a copy of the instance only if the class is parameterized with a particular trait that has a representation type. I can get that to happen pretty easily. What I can’t do is put a sensible return type that method:
case class Foo[+A](a: A) {
// Compiles
def gotFooBar(implicit evidence: A <:< Bar[_]) = copy(a = a.Copy())
// Does not compile
def gotFooBar(implicit evidence: A <:< Bar[_]): Foo[A] = copy(a = a.Copy())
}
trait Bar[+B <: Bar[B]] {
def Copy(): B // Return underlying type
}
case class Grill() extends Bar[Grill] {
def Copy() = Grill()
}
What is the return type of that function, or perhaps more importantly, how would I set up the types so that that was the return type? Could someone also point out how the real return type could be a supertype of Foo[A]?
Well, since you only require
Bar[_]you getAnyas result of callinga.Copy. You need a type parameter for thegotFooBarmethod:The second question is, how to enforce that
Foo[B]is a supertype ofFoo[A]. You just need to addAas a lower bound forB: