I would like to know if it is possible to abstract the copy method of case classes. Basically I have something like sealed trait Op
and then something like case class Push(value: Int) extends Op
and case class Pop() extends Op
.
The first problem: A case class without arguments/members does not define a copy method. You can try this in the REPL.
scala> case class Foo()
defined class Foo
scala> Foo().copy()
<console>:8: error: value copy is not a member of Foo
Foo().copy()
^
scala> case class Foo(x: Int)
defined class Foo
scala> Foo(0).copy()
res1: Foo = Foo(0)
Is there a reason why the compiler makes this exception? I think it is rather unituitive and I would expect every case class to define a copy method.
The second problem: I have a method def ops: List[Op]
and I would like to copy all ops like ops map { _.copy() }
. How would I define the copy method in the Op
trait? I get a "too many arguments" error if I say def copy(): Op
. However, since all copy() methods have only optional arguments: why is this incorrect? And, how do I do that correct? By making another method named def clone(): Op
and write everywhere def clone() = copy()
for all the case classes? I hope not.
Upvoted Ben's answer. But what if you wanted to something like this:
sealed trait Op
case class Push(value: Int, context:String) extends Op
case class Pop(context:String) extends Op
val stackOps = List(Push(3, "foo"), Pop("foo"))
def copyToContext(newContext:String, ops:List[Op]): List[Op] = {
// ... ?
}
val changedOps = copyToContext("bar", stackOps)
// would return: List(Push(3, "bar"), Pop("bar"))
The copy methods are only generated if there is no member named"copy" in the class, directly defined or inherited.
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