【发布时间】:2017-06-23 20:54:00
【问题描述】:
注意:我正在学习无形,所以如果我错过任何细节,请要求澄清。
背景:
在练习 Shapeless 时,我正在为固定长度格式构建编码/解码解决方案。这个想法是每个case class 都有自己的编码器/解码器,定义为与其属性对齐的HList。
即使两个类共享相同的属性,它们的编码也可能不同。每个字段的描述将包含一些 (4) 值。但这在问题中并不重要。
问题:
我声明了一个示例案例类及其编码器:
case class Employee(name: String, number: Int, manager: Boolean)
object Employee {
implicit val employeeEncoder =
FLEncoder.fixed((s: String) => s) ::
FLEncoder.fixed((s: String) => s) ::
FLEncoder.fixed((s: Int) => s.toString) ::
FLEncoder.fixed((s: Boolean) => s.toString) ::
HNil
}
所以我employeeEncoder的类型很漂亮:
::[FLEncoder[String], ::[FLEncoder[String], ::[FLEncoder[Int], ::[FLEncoder[Boolean], HNil]]]]
现在,编码器implicitly 正在寻找FLEncoder[Employee],我希望它可以是上述实现。
我已使用此解决方案为元组组合 TypeClass:
- Composing typeclasses for tuples in Scala
- https://www.scala-exercises.org/shapeless/auto_typeclass_derivation
但我得到了:
Error:(69, 17) could not find implicit value for parameter enc: test.FLEncoder[test.Employee]
println(encode(example))
如果我单独声明这些编码器,它们工作正常
implicit val a = fixed((s: String) => s)
implicit val b = fixed((s: Int) => s.toString)
implicit val c = fixed((s: Boolean) => s.toString)
问题:
所以基本上,如何使用Shapeless 让它知道这个Hlist 是对齐case class 的编码器类型?
在 scodec 中解决了类似的问题。如果您在此处查看演示: https://github.com/atais/Fixed-Length/blob/03b395947a6b00e548ea1e76a9660e471f136565/src/main/scala/test/Fixed.scala
你可以做这样的转变:
case class Person(name: String, age: Int)
val pc: Codec[shapeless.::[String, shapeless.::[Int, HNil]]] = (("name" | fixed(10, '_')) :: ("age" | fixed(6, '0').narrow[Int](strToInt, _.toString)))
val personCodec: Codec[Person] = pc.as[Person]
但我不知道在我的情况下如何使用TransformSyntax.as。
【问题讨论】:
-
你能给我们
FLEncoder[T]的特征,以便更好地了解你想要实现的目标吗?同时,请查看stackoverflow.com/questions/44358332/…,其中给出了完整的示例(其中一部分在我的解决方案中)。 -
编码器在
Main.scala的GitHub上封闭
标签: scala typeclass shapeless fixed-width scodec