如何在 scala 中优雅地聚合 case-class?
how to aggregate case-class in scala gracefully?
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
)
}
}
我想聚合case-class('value'),我觉得这个手工实现在n很大的时候(比如n=500?)不优雅
案例 类 的字段是 immutable,return 一个包含所有更新字段的新实例。
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)
这是一个在 Scala3 中仅适用于 build-in api 的解决方案:
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)))
那么我们可以定义Value
class为:
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)
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
)
}
}
我想聚合case-class('value'),我觉得这个手工实现在n很大的时候(比如n=500?)不优雅
案例 类 的字段是 immutable,return 一个包含所有更新字段的新实例。
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)
这是一个在 Scala3 中仅适用于 build-in api 的解决方案:
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)))
那么我们可以定义Value
class为:
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)