case class value(x1:Long, x2: Double, ..., xk: Long, ... ,xn:Int) {
def add(rValue: Value): Value = {
Value(
x1 = x1 rValue.x1,
...
xk = xk rValue.xk,
...
xn = xn rvalu.xn
)
}
}
I want to aggregate case-class('value'), I think this manual implementation is not elegant when n is large (such as n = 500?)
CodePudding user response:
Fields in case classes are immutable, return a new instance with all the updated fields.
case class Value(x: Int, y: Int) {
def (other: Value): Value =
Value(x other.x, y other.y)
}
Value(10, 20) Value(10, 20)
//res0: Value = Value(20,40)
Value(10, 20) Value(20, 30) Value(30, 50)
//res1: Value = Value(60,100)
CodePudding user response:
Here is a solution works in Scala3 with build-in api only:
trait Add[N] { def add(x: N, y: N): N }
object Add:
import scala.deriving.Mirror.ProductOf
given Add[Int] = _ _
given Add[Long] = _ _
given Add[Float] = _ _
given Add[Double] = _ _
given Add[EmptyTuple] = (_, _) => EmptyTuple
given [H, T <: Tuple](using ha: Add[H], ta: Add[T]): Add[H *: T] =
case (hx*:tx, hy*:ty) => ha.add(hx, hy) *: ta.add(tx, ty)
given [P <: Product](using p: ProductOf[P], a: Add[p.MirroredElemTypes]): Add[P] =
(x, y) => p.fromProduct(a.add(Tuple.fromProductTyped(x), Tuple.fromProductTyped(y)))
Then we can define Value
class as:
scala> case class Value(x1: Int, x2: Float, x3: Double):
| def add(that: Value): Value = summon[Add[Value]].add(this, that)
|
scala> Value(1, 2, 3).add(Value(3, 4, 5))
val res0: Value = Value(4,6.0,8.0)