8

次のように、封印されたケース クラス ファミリのコーデックを一般的に簡単に派生させることができます。

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))
}

ただし、型メンバーを基本クラスに追加すると、封印された特性によって制限されていても、それを行うことはできなくなります。

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)
}

私が望むものを達成する方法はありますか?そうでない場合、似たようなものを得るために何を変更できますか?

4

1 に答える 1