Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case class copy() method abstraction

Tags:

copy

scala

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.

like image 928
Joa Ebert Avatar asked May 26 '10 09:05

Joa Ebert


2 Answers

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"))
like image 150
huynhjl Avatar answered Sep 30 '22 00:09

huynhjl


  1. What would be the benefit of a compiler generated copy method for case classes without any arguments? This would just return a new Foo, and not copy anything.
  2. To quote Lukas Rytz (I believe he implemented it):
The copy methods are only generated if there is no member named"copy" in the class, directly defined or inherited.
like image 32
Mirko Stocker Avatar answered Sep 30 '22 00:09

Mirko Stocker