I am working on a side project, trying to implement immutable aggregates in Scala. My idea is to have base trait AggregateRoot
with some common behaviors. Child classes would be actual aggregates modeled as a case classes. For now, there is one thing that I don't like, and that is that I cannot call copy
method from the base trait for two reasons:
- I don't have access to
copy
method inside of the base trait - I have no idea how many parameters
copy
method will have
I have some basic knowledge of shapeless library and I thought that it might help in this case. My idea is pass list of tagged fields to the base method in the trait which will replace them and return new instance of the case class. As a step in that direction I am trying to create method that will copy one single field for the beginning using shapeless, but I am getting the same error all the time, that compiler cannot find the implicit for updater.
Here is the simplified code fragment that I am trying to use:
import shapeless._
import shapeless.labelled.FieldType
import shapeless.ops.record.Updater
import shapeless.record._
import shapeless.syntax.singleton._
trait AggregateRoot[T <: AggregateRoot[T]] {
self: T =>
def makeCopy[L <: HList, K, V](ft: FieldType[K, V])(
implicit
labeledGen: LabelledGeneric.Aux[T, L],
updater: Updater.Aux[L, FieldType[K, V], L],
witness: Witness.Aux[K]): T = {
val labeledHList = labeledGen.to(this)
val result = labeledHList.updated(witness, ft)
labeledGen.from(result)
}
}
case class User(id: String, age: Int) extends AggregateRoot[User]()
val user1 = User("123", 10)
val ageChange = "age" ->> 22
val user2 = user1.makeCopy(ageChange)
Since I am not experienced shapeless user, I am not sure why it cannot find requested implicit. Version of shapeless is 2.3.3.
withX
methods that can be used instead ofcopy
– Luis Miguel Mejía Suárez