Search code examples
scalatraitscase-class

Return a case class that extends a trait


I need to define to return a case class that extends a trait:

trait Id {
  def id: Long
}

case class Person(name: String)

val john = Person("John") 
val johnWithId: Person with Id = /*person -> 123L*/ ???

Any idea how can I achieve that?

I'm trying to reduce the duplication of code, that's why I didn't declare a trait Person like this:

trait Id {
  def id: Long
}

trait Person {
  def name: String
}

case class PersonWithoutId(name: String) extends Person

case class PersonWithId(name: String, id: Long) extends Person with Id

val john = PersonWithoutId("John")
val johnWithId: Person with Id = PersonWithId(person.name, 123L)

Any idea how to achieve that?


Solution

  • A bit round-about way:

    case class WithId[A](id: Long, value: A) extends Id
    object WithId {
      implicit def getValue[A](x: WithId[A]): A = x.value
    }
    
    // elsewhere
    val johnWithId = WithId(123, john)
    

    johnWithId doesn't extend Person (so e.g. johnWithId.isInstanceOf[Person] is false), but can still be used where a Person is expected and getValue.