There are two problems in your code:
copy not defined in the tag, so you need to have something specific in the tag that you can use.- For
update return T instead of Model , each Model must know its actual subtype.
You can fix it as follows:
trait Model[T <: Model[T]] { def id: String def updated: Date def withDate(d: Date): T } case class C1(id: String, updated: Date, foo: String) extends Model[C1] { def withDate(d: Date) = copy(updated = d) } case class C2(id: String, updated: Date, bar: Int) extends Model[C2] { def withDate(d: Date) = copy(updated = d) } object Model { def update[T <: Model[T]](model: T): T = { model.withDate(new Date) // This code does not compile. } }
So now it works:
scala> val c1 = C1("test", new Date, "foo") c1: C1 = C1(test,Mon Apr 21 10:25:10 CDT 2014,foo) scala> Model.update(c1) res0: C1 = C1(test,Mon Apr 21 10:25:17 CDT 2014,foo)
source share