3

有了这个例子,

import io.circe.generic.auto._
import io.circe.shapes._
import io.circe.parser._
import io.circe.syntax._
import shapeless._

case class A[T <: HList](name: String, params: T)

当我用非空 HList 实例化这个案例类时,没有问题:

scala> A("name", "a" :: HNil).asJson
res1: io.circe.Json =
{
  "name" : "name",
  "params" : [
    "a"
  ]
}

但是,当这个 HList 只是 HNil 时,我收到以下错误:

scala> A("name", HNil).asJson
<console>:29: error: could not find implicit value for parameter encoder: io.circe.Encoder[A[shapeless.HNil.type]]
   A("name", HNil).asJson
                   ^

我读过这个问题,他们谈论案例对象编码器,但它不适用于 HNil(HNil 是案例对象),我在文档中看到了任何关于它的内容。仅供参考,我正在使用 circe 0.6.1

任何想法?

4

2 回答 2

4

这是因为静态类型 ofHNilHNil(即 it's HNil.type)更具体。以下将按预期工作:

scala> A("name", HNil: HNil).asJson.noSpaces
res0: String = {"name":"name","params":{}}

我们可以为 提供EncoderDecoder实例,但一般来说,当您使用和的静态类型HNil.type构造类型时,为了简单起见,我们决定只为 提供实例。HNil::HNilHNilHNil

这个问题出现在其他地方,包括 Shapeless 本身,搜索HNil: HNil返回 30 多起的事件。

于 2017-01-12T16:13:28.273 回答
2

Travis 的回答是有效的,您当然可以HNil使用类型注释进行编码。我没有足够的声誉,所以我无法评论他的回答,但我注意到非空HList的 s 编码为 JSON 数组,而空Hlist的编码为空的 JSON 对象。

这是此行为的快速代码示例。

@ (1 :: 2 :: "foo" :: HNil).asJson.noSpaces 
res1: String = """[1,2,"foo"]"""
@ (HNil: HNil).asJson.noSpaces 
res12: String = "{}"
于 2017-01-12T16:35:51.647 回答