当HList参数是HNil时如何编码Json?

时间:2017-01-12 16:04:18

标签: scala shapeless circe

有了这个例子,

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实例化这个case类时,没有问题:

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
                   ^

我已经阅读了question,他们谈论了案例对象编码器,但它不适用于HNil(HNil是案例对象),而且我已经看到了有关它的任何内容文件。仅供参考,我使用的是0.6.1

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

这是因为HNil的静态类型比HNil更具体(即它是HNil.type)。以下内容将按预期工作:

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

我们可以Encoder提供DecoderHNil.type个实例,但通常在构建HNil和{{1}的类型时::的静态类型为HNil,为了简单起见,我们决定仅为HNil提供实例。

此问题出现在其他地方,包括在Shapeless本身,搜索HNil会返回三十多次。

答案 1 :(得分:2)

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

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

@ (1 :: 2 :: "foo" :: HNil).asJson.noSpaces 
res1: String = """[1,2,"foo"]"""
@ (HNil: HNil).asJson.noSpaces 
res12: String = "{}"