Is there a way to rely on methods defined in case class in a trait? E.g., copy: the following doesn't work. I'm not sure why, though.
trait K[T <: K[T]] {
val x: String
val y: String
def m: T = copy(x = "hello")
def copy(x: String = this.x, y: String = this.y): T
}
case class L(val x: String, val y: String) extends K[L]
Gives:
error: class L needs to be abstract, since method copy in trait K of type
(x: String,y: String)L is not defined
case class L(val x: String, val y: String) extends K[L]
^
A solution is to declare that your trait must be applied to a class with a copy method:
trait K[T <: K[T]] {this: {def copy(x: String, y: String): T} =>
val x: String
val y: String
def m: T = copy(x = "hello", y)
}
(unfortunately you can not use implicit parameter in the copy method, as implicit declaration is not allowed in the type declaration)
Then your declaration is ok:
case class L(val x: String, val y: String) extends K[L]
(tested in REPL scala 2.8.1)
The reason why your attempt does not work is explained in the solution proposed by other users: your copy
declaration block the generation of the "case copy
" method.
I suppose that having method with name copy in trait instructs compiler to not generate method copy in case class - so in your example method copy is not implemented in your case class. Below short experiment with method copy implemented in trait:
scala> trait K[T <: K[T]] {
| val x: String
| val y: String
| def m: T = copy(x = "hello")
| def copy(x: String = this.x, y: String = this.y): T = {println("I'm from trait"); null.asInstanceOf[T]}
| }
defined trait K
scala> case class L(val x: String, val y: String) extends K[L]
defined class L
scala> val c = L("x","y")
c: L = L(x,y)
scala> val d = c.copy()
I'm from trait
d: L = null
You can run repl with $scala -Xprint:typer. With parameter -Xprint:typer you can see what exactly happening when you create trait or class. And you will see from output that method "copy" not created, so compiler requests to define it by yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With