scala / pickling

Fast, customizable, boilerplate-free pickling support for Scala
lampwww.epfl.ch/~hmiller/pickling
BSD 3-Clause "New" or "Revised" License
831 stars 79 forks source link

Pickling an abstract type #97

Open julienrf opened 10 years ago

julienrf commented 10 years ago

Consider the following trait:

trait Module {

  type User <: UserLike

  trait UserLike {
    def name: String
  }

}

I’d like to write a function that pickles a value of type User, which is abstract. Here is what I came out with:

trait ModuleUsage extends Module {
  import scala.pickling._

  def pickle(u: User)(implicit p: SPickler[User], t: FastTypeTag[User]): Unit = {
    import binary._
    println(u.pickle)
  }

}

This trait can then be used as follows:


object ModuleUsageImpl extends ModuleUsage with App {

  // Implementation of the abstract type `User`
  case class User(name: String) extends UserLike

  // Why do I need these imports?
  import scala.pickling._
  import scala.pickling.binary._

  pickle(User("Heather"))

}

My problem is that I’d like to avoid the imports to at the ModuleUsageImpl site, especially the scala.pickling.binary._ import. By the way, if I import scala.pickling.json._ at this place, the pickling format is still binary (which is the one that is imported in the pickle function). Maybe my pickle function is not taking the right implicit parameters?

julienrf commented 10 years ago

If I trade the implicit parameters for implicit vals, the above code does not compile anymore:

trait ModuleUsage extends Module {
  import scala.pickling._

  implicit def p: SPickler[User]
  implicit def t: FastTypeTag[User]

  def pickle(u: User): Unit = {
    import binary._
    println(u.pickle)
  }

}

object ModuleUsageImpl extends ModuleUsage with App {

  case class User(name: String) extends UserLike

  import scala.pickling._
  import scala.pickling.binary._

  implicit val p = implicitly[SPickler[User]]
  implicit val t = implicitly[FastTypeTag[User]]

  pickle(User("Heather"))

}

I get the following error:

[info] pickling.this.SPickler.genPickler is not a valid implicit value for scala.pickling.SPickler[ModuleUsageImpl.User] because:
[info] stepping aside: repeating itself
[info]   implicit val p = implicitly[SPickler[User]]
[info]                              ^