4

Let's say I have two case classes:

case class C1(a: Int, b: String)
case class C2(a: Int, b: String, c: Long = 0)

I want to convert instance of C1 to C2 and then set additional field c. I found out the following solution:

C1.unapply(C1(1, "s1")).map(v => C2(v._1, v._2, 7l))

But specifying parameters one by one is not applicable, because real case class will have at least 15 params. Any ideas how to solve it?

Bohdan Petrenko
  • 997
  • 2
  • 17
  • 34

2 Answers2

5

This solution can be done by doing something like this thread.

How to append or prepend an element to a tuple in Scala

implicit class TupOps2[A, B](val x: (A, B)) extends AnyVal {
  def :+[C](y: C) = (x._1, x._2, y)
  def +:[C](y: C) = (y, x._1, x._2)
}

Usage:

val c1      = new C1(1, "s1")
val longVal = 0L

scala> C1.unapply(c1).map(r => (r :+ longVal))
res0: Option[(Int, String, Long)] = Some((1,s1,0))

scala> C1.unapply(c1).map(r => (C2.apply _) tupled (r:+ longVal))
res45: Option[C2] = Some(C2(1,s1,0))

Hope it helps :)

Rex
  • 558
  • 2
  • 9
  • 1
    Yes, it helps. Thank you. But it's necessary to add [Shapeless library](https://github.com/milessabin/shapeless) to the project – Bohdan Petrenko Apr 02 '19 at 14:47
  • 1
    No need.. all you have to do is just add the `implicit`. I updated the answer. – Rex Apr 02 '19 at 17:08
4

I think what you need is closer to

https://github.com/scalalandio/chimney

case class MakeCoffee(id: Int, kind: String, addict: String)
case class CoffeeMade(id: Int, kind: String, forAddict: String, at: ZonedDateTime)

val command = MakeCoffee(id = Random.nextInt,
                         kind = "Espresso",
                         addict = "Piotr")

import io.scalaland.chimney.dsl._

val event = command.into[CoffeeMade]
  .withFieldComputed(_.at, _ => ZonedDateTime.now)
  .withFieldRenamed(_.addict, _.forAddict)
  .transform
Felix
  • 8,385
  • 10
  • 40
  • 59
  • Also, when you say "at least 15 params" remember that you are also limited to a maximum of 22 so you will quickly hit that ceiling. Maybe `HList` from shapeless is a better fit for those kinds of classes. – Felix Apr 02 '19 at 18:04