My domain classes are case classes and I have general engine/transformer classes that operate on them. I make use of case class functionality such as copy()
and would like to do that while treating the classes generically, here is a simple example:
trait Fruit { val color: String }
case class Apple (color: String = "red") extends Fruit
case class Banana (color: String = "yellow") extends Fruit
case class Orange (color: String = "orange") extends Fruit
val apple = new Apple
val newApple1 = apple.copy(color = "green") // compiles fine
object Transformer {
def apply(fruit: Fruit): Fruit = {
fruit.copy(color = "green") // does not compile, "Cannot resolve symbol copy"
}
}
val newApple2 = Transformer(apple)
newApple2
In this example the first call to copy()
works fine, but trying to do the same kind of operation within the apply()
method of the Transformer
class does not, I am assuming because Scala does not know that Fruit
is a case class and thus has the runtime-generated copy()
method.
I've tried various typecasts, for example making Fruit
an abstract class or having it extend scala.Product
(which internally is the closest ancestor to the case class) but this doesn't make the copy()
method available.
I would rather not implement the copy method myself if I can avoid it, though with reflection or shapeless it can probably be done in a generic way that would work.
There are a few other similar questions here on StackOverflow but I have not see an answer that addresses this, thanks for any info.
EDIT: My question is similar to this recent question however the answers there did not satisfy me for these reasons:
- The accepted solution suggested implementing a
copyWithId()
method, or, in other words, a special-purposecopy()
method that takes one or more specific parameters, whereas I want to use the very versatile case classcopy()
method which accepts variable parameters. - The solutions proposed there use shapeless or lenses and a lot of Scala "magic" which it seems to me should not be necessary since, as my example shows, the
copy()
implementation that I'm after is already in scope, but is just not available because the correct data type can't be inferred. I'm hoping instead to gain access to thecopy()
with the right kind of typecast.