ich einfach allgemein einen Codec für ein abgedichtetes Gehäuse Familie wie folgt ableiten:für ein abgedichtetes Gehäuse Familie ableiten circe Codec, wo die Basismerkmal a (verschlossen) Typ hat Mitglied
import io.circe._
import io.circe.generic.auto._
sealed trait Base
case class X(x: Int) extends Base
case class Y(y: Int) extends Base
object Test extends App {
val encoded = Encoder[Base].apply(Y(1))
val decoded = Decoder[Base].apply(encoded.hcursor)
println(decoded) // Right(Y(1))
}
Allerdings, wenn ich hinzufügen ein Typ Element der Basisklasse kann ich es nicht mehr tun, auch wenn es von einem versiegelten Zug begrenzt ist:
import io.circe._
import io.circe.generic.auto._
sealed trait Inner
case class I1(i: Int) extends Inner
case class I2(s: String) extends Inner
sealed trait Base { type T <: Inner }
case class X[S <: Inner](x: S) extends Base { final type T = S }
case class Y[S <: Inner](y: S) extends Base { final type T = S }
object Test extends App {
val encodedInner = Encoder[Inner].apply(I1(1))
val decodedInner = Decoder[Inner].apply(encodedInner.hcursor) // Ok
println(decodedInner) // Right(I1(1))
// Doesn't work: could not find implicit for Encoder[Base] etc
// val encoded = Encoder[Base].apply(Y(I1(1)))
// val decoded = Decoder[Base].apply(encoded.hcursor)
// println(decoded)
}
gibt es eine Weise, die ich erreichen kann, was ich will? Wenn nicht, was kann ich ändern, um etwas Ähnliches zu bekommen?
Was ist, wenn Sie mit dem Aux-Muster versucht haben? z.B. 'type Aux [A <: Input] = Base {Typ T = A}' und dann von 'Aux'? Brauchst du es wirklich, um ein Mitglied des Typs zu sein? – pyrospade
In der Tat, scheint Ihr Fall Klassen könnte ein 'Inneres 'als ihr Argument anstelle eines' S <: Inner nehmen. – pyrospade
Ich habe eine Antwort hinzugefügt, aber seitdem überarbeitet, um weitere Details und Erklärungen sowie eine bessere Implementierung hinzuzufügen. – pyrospade