0

Say I have the following trait:

trait T {
    val x: Int
}

def foo(i: Int): T

I would like to bet able to write and read this trait using upickle without knowing what the specific class is. e.g.:

upickle.default.write(foo(3))

Such that I could elsewhere define foo to be something like:

case class A(x: Int)

def foo(i: Int): T = A(i)

I am thinking I need to define an implicit Writer as a member of T but I don't know what the appropriate syntax would be?

user79074
  • 4,937
  • 5
  • 29
  • 57

1 Answers1

0
trait T {
  val x: Int
}
object T {
  implicit val rw: ReaderWriter[T] = ...
}

The problem is what to put into the ... part: if you have a T value, you can just store its x:

... = readwriter[Int].bimap[T](
  t => t.x,
  i => new T { val x = i }
)

The problem with this solution is that reading a written A(3) won't return an A. And this isn't really solvable without making T sealed or otherwise handling a specific set of subclasses only.

You could include a class name as well when writing, but that won't help if the class has any fields other than x to store:

class B(override val x: Int, y: String) extends T

If T is sealed, you just write

... = macroRW
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487