amnaredo / test

0 stars 0 forks source link

Retain unused type parameters #113

Open amnaredo opened 3 years ago

amnaredo commented 3 years ago

The following trait hierarchy cannot be serialised with uPickle:

sealed trait Delta[A, B]
object Delta {
  case class Insert[A, B](key: A, value: B) extends Delta[A, B]
  case class Remove[A, B](key: A) extends Delta[A, B]
  case class Clear[A, B]() extends Delta[A, B]
}

The reason is that Clear[A, B]() does not bind its type parameters to arguments. As a consequence, every Clear[A, B] instance becomes Clear[Nothing, Nothing], leading to type mismatches.

I came up with a quick workaround (which requires https://github.com/tindzk/upickle/commit/4b1345f288b9d4a8bcbd1675503eb50f06d8cfef):

implicit def DictDeltaW[A: W, B: W]: W[Dict.Delta[A, B]] = W[Dict.Delta[A, B]] {
  case x: Dict.Delta.Insert[A, B] => upickle.writeJs(x)
  case x: Dict.Delta.Remove[A, B] => upickle.writeJs(x)
  case x: Dict.Delta.Clear[A, B] => upickle.writeJs[Dict.Delta[A, B]](x)
}

implicit def DictDeltaR[A: R, B: R]: R[Dict.Delta[A, B]] = R[Dict.Delta[A, B]] {
  implicitly[R[Dict.Delta.Insert[A, B]]].read
    .orElse(implicitly[R[Dict.Delta.Remove[A, B]]].read)
    .orElse(implicitly[R[Dict.Delta.Clear[Nothing, Nothing]]].asInstanceOf[R[Dict.Delta.Clear[A, B]]].read)
}

ID: 70 Original Author: tindzk

amnaredo commented 3 years ago

This now works in the generic-adts development branch

Original Author: lihaoyi

amnaredo commented 3 years ago

Fixed in master

Original Author: lihaoyi