A couple of problems here:1. case classes shouldn't subclass other case classes. This can cause lots of problems and is formally deprecated in 2.8Make Shape into an abstract class
sealed abstract class Shape { def color:String}2. why is the shapes collection both a var and a mutable collection?This mixes of idioms, choose one or the other

To answer your original question, to copy the object you can pattern match on it:def put(shape:S) : Unit = shapes += shape match { case s:Circle => s.copy(color="red")
case s:Square => s.copy(color="red") }There's no need to match the default case as Shape is sealed and you want the compiler to help you out here and warn of shapes you've missed

Though the return type of copy() is covariant, so that Square#copy
returns a Square and Circle#copy returns a Circle, it's legal to write
the following class that doesn't take advantage of the covariance:

Thus, when you have a type upper bound [here, S<:Shape], the compiler can
only verify what it knows about the Shape class (which is that Shape#copy
returns Shape). You can't put the Shape into a collection of S, because S
can be constrained to be a particular subtype of Shape, but the return
value has no such guarantee.

You said S is a subclass of Shape, but then tried to insert a Shape (which is the result of the "copy" method on Shape) on it.That's the same of declaring a variable to be String, a subclass of AnyRef, and then trying to put an AnyRef on it.
Instead of declaring ListBuffer as type S, you should have declared it as type Shape.Of course, the copy method called will be Shape's, not Circle's or Square's, both of which have a different type signature anywya, so you won't get a Circle or Square properly copied. That's not really related to declaring ListBuffer as Shape, however.
Instead of relying on the case class copy method named and default parameters, which _cannot_ help you here, as long as you treat the object as a "shape", you should provide your own copy method, receiving a Map[String,String], returning a Shape, and overridden in Circle and Square.
That would really be best, because case classes don't work well in an hierarchy. The problem with your copy method is, in fact, an example of where case classes break down.
On Sun, Dec 20, 2009 at 1:25 PM, linjie nie <nielinjie [at] gmail [dot] com> wrote:

A couple of problems here:1. case classes shouldn't subclass other case classes. This can cause lots of problems and is formally deprecated in 2.8
Make Shape into an abstract class
sealed abstract class Shape { def color:String}2. why is the shapes collection both a var and a mutable collection?This mixes of idioms, choose one or the other

To answer your original question, to copy the object you can pattern match on it:def put(shape:S) : Unit = shapes += shape match { case s:Circle => s.copy(color="red")
case s:Square => s.copy(color="red") }There's no need to match the default case as Shape is sealed and you want the compiler to help you out here and warn of shapes you've missed

The biggest issue is that the code you *want* is not really how scala generic work, more like C++ templates. In C++, templates are evaluated at call sites, and needed code is generated for you. In scala, the code is compiled and then call sites make use of this generic form (i.e. there is erasure).

So.... I don't think you can define a type that will use the specific copy method of the class (i.e. with all the appropriate defaults), without going through some extra hoops. You have to ensure that you're using normal runtime-polymorphism.

Either way, it's not quite the same as in C++ where the compiler will write the code for you.

Anyway, as an aside, the PaintingWorkshop (as defined) is not very useful. If it's designed to work against shapes, the Type constraints on it limit it to only working with a particular shape subclass. Perhaps describing the goal you're trying to achieve would be more useful?

A couple of problems here:1. case classes shouldn't subclass other case classes. This can cause lots of problems and is formally deprecated in 2.8
Make Shape into an abstract class
sealed abstract class Shape { def color:String}2. why is the shapes collection both a var and a mutable collection?This mixes of idioms, choose one or the other

To answer your original question, to copy the object you can pattern match on it:def put(shape:S) : Unit = shapes += shape match { case s:Circle => s.copy(color="red")
case s:Square => s.copy(color="red") }There's no need to match the default case as Shape is sealed and you want the compiler to help you out here and warn of shapes you've missed