2

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?

4

1 回答 1

4

我认为你不能不以任何涉及 circe 的方式影响你的 apply 方法签名。如果可以的话,这意味着circe.auto_能够为任何类型的 T 引入隐式解码器,这是不正确的。

AFAIK,没有比Decoder在你的函数中添加一个隐式来表示它实际上知道如何处理这种类型更好的类型注释(如果你愿意,你可以使用这个T: Decoder版本,但它最终是一样的)。

于 2016-12-09T15:24:25.267 回答