Kevin Meredith Kevin Meredith - 3 months ago 21
Scala Question

Define `copy` for `trait`

Given:

sealed trait X { val x: String }
case class A(x: String) extends X
case class B(x: String) extends X


I defined a
copy
method at the
X
trait:

def copy(x: X, newValue: String): X = x match {
case A(_) => A(newValue)
case B(_) => B(newValue)
}


However, I thought that I could do better, i.e be precise.

Because, technically, just because an
A
is input, a
B
could be output since a
B
is a sub-class of
X
.

So I tried:

def copyBetter[T <: X](x: T, newValue: String): T = x match {
case A(_) => A(newValue)
case B(_) => B(newValue)
}


But, I got compile-time errors:

<console>:17: error: type mismatch;
found : A
required: T
case A(_) => A(newValue)
^
<console>:18: error: type mismatch;
found : B
required: T
case B(_) => B(newValue)
^


How can I implement
copyBetter
with the given signature?

Answer

I suggest the following:

def copyBetter(x: _ <: X, newValue: String): X = x match {
  case A(_) => A(newValue)
  case B(_) => B(newValue)
}
Comments