2

对于“大”编解码器,当直接从HLists 创建编解码器并应用.dropUnits

( ignore(6) ::
  uint(2) ::
  uint(30) ::
  int(4) ::
  int(8) ::
  uint(10) ::
  bool(1) ::
  int(28) ::
  int(27) ::
  uint(12) ::
  uint(9) ::
  uint(6) ::
  int(2) ::
  ignore(3) ::
  bool(1) ::
  uint(19)
).dropUnits.as[SomeBigCaseClass]

创建编解码器似乎要快得多~,然后.hlist像这样应用:

( ignore(6) ~
  uint(2) ~
  ...
).hlist.dropUnits.as[SomeBigCaseClass]

但这似乎行不通。

Could not prove that this.Out can be converted to/from reports.SomeBigCaseClass.
  ).hlist.dropUnits.as[SomeBigCaseClass]
                      ^

我发现的最简单的解决方案对我来说已经足够好了,就是省略Unit内联值。

( (ignore(6) dropLeft 
   uint(2)) :: 
  ...
).as[SomeBigCaseClass]

对于有许多忽略的编解码器,此功能将非常受欢迎。我究竟做错了什么?我完全错过了重点.hlist吗?

4

1 回答 1

1

hlist组合器将 a inCodec[A]转换为 a Codec[A :: HNil]。这通常与flatZip需要HList基于编解码器的其他组合器一起使用,例如 .

重复使用~运算符会创建一个基于左关联Tuple2的结构。例如,int8 ~ bool ~ int8有类型Codec[((Int, Boolean), Int)]。最新的编解码器快照 1.7.0-SNAPSHOT(虽然不是 1.7.0-RC1)具有flattenLeftPairs将左关联元组编解码器转换为等效HList编解码器的方法。

未来版本的 scodec 将有一个类似~但不是嵌套Tuple2实例的组合器,它将创建TupleN实例。例如:int8 ~~ bool ~~ int8将有类型Codec[(Int, Boolean, Int)]. 不过,这还没有集成。通过减少分配的元组数量,这既具有性能优势,也具有便利优势,因为它允许通过绑定到案例类widenOpt(SomeBigCaseClass.apply, SomeBigCaseClass.unapply)

最后,观察到的编译器性能问题dropUnits确实是组合器定义方式的问题。这已在 scodec-core 1.7.0-SNAPSHOT 中得到修复(虽然不是 1.7.0-RC1)。请参阅https://github.com/scodec/scodec/issues/41

于 2015-01-26T14:23:31.943 回答