В Scala, как создать признак для классов с функциями, использующими разные границы контекста

Теперь я хочу сериализовать / десериализовать данные Json, и на выбор есть несколько библиотек JSON. Тем не менее, они используют разные контекстные границы для кодирования / декодирования, что затрудняет определение их характеристик.

trait JsonLib {
  // def writes[T](data: T): String
  // def reads[T](jsonStr: String): Option[T]
}

object JsonCirce extends JsonLib {
  import io.circe.Encoder._
  import io.circe.Decoder._

  def writes[T: Encoder](data: T): String = ...
  def reads[T: Decoder](jsonStr: String): Option[T] =
}

//spray-json
object JsonSpray extends JsonLib {
  import spray.json._

  def writes[T: JsonWriter](data: T): String = ...

  def reads[T: JsonReader](jsonStr: String): Option[T] = ...
}

Есть ли способ определить записи / чтения в черту?

1 ответ

Решение

Вы можете обобщить классы типов, используя более высокие типы типов, такие как:

import scala.language.higherKinds
import scala.util.Try
import spray.json._
import DefaultJsonProtocol._

trait JsonLib[R[_], W[_]] {
  def writes[T: W](data: T): String

  def reads[T: R](jsonStr: String): Option[T]
}

//spray-json
object JsonSpray extends JsonLib[JsonReader, JsonWriter] {

  override def writes[T: JsonWriter](data: T): String =
    data.toJson.compactPrint

  override def reads[T: JsonReader](jsonStr: String): Option[T] =
    Try(jsonStr.parseJson.convertTo[T]).toOption
}

// Test
JsonSpray.writes(List(1, 2))
JsonSpray.reads[List[Int]]("[1,2]")
Другие вопросы по тегам