问题
I have a trait used to inject json decoder as dependency to components of my project:
trait JsonDecoder {
def apply[T](s: String): Option[T]
}
When I try to implement it with Circe:
import io.circe.generic.auto._
import io.circe.parser.decode
case class CirceJsonDecoder() extends JsonDecoder {
def apply[T](s: String): Option[T] = {
decode[T](s).fold(_ => None, s => Some(s))
}
}
and run:
case class C()
def test(d: JsonDecoder) = d[C]("{}")
test(CirceJsonDecoder())
it does not compile with error:
could not find implicit value for parameter decoder: io.circe.Decoder[T]
I tried to add ClassTag
, TypeTag
or WeakTypeTag
context bounds for T
but it still can not find implicit value for Decoder
.
I can not add Decoder
context bound or implicit parameter to JsonDecoder.apply
because components what use it should not know about implementation details.
How should I provide implicit io.circe.Decoder
? May be there is some way to get it from TypeTag
?
回答1:
I don't think you can without affecting your apply method signature in any way involving circe.
If you could, it'd mean circe.auto_
is capable of bringing an implicit decoder in scope for any type T, which is not true.
AFAIK, there's no better type annotation than adding an implicit Decoder
to your function to signal circe that it actually knows how to handle this type (if you prefer, you can use the T: Decoder
version, but it's the same in the end).
来源:https://stackoverflow.com/questions/41058947/generic-json-decoder-trait-with-circe-implementation