2

我正在尝试在现有项目中使用鉴别器,我猜我的课程有问题。

考虑这个编解码器示例。如果我将TurnLeft其编解码器更改为

sealed class TurnLeft(degrees: Int) extends Command {
  def getDegrees: Int = degrees
}
implicit val leftCodec: Codec[TurnLeft] = uint8or16.xmap[TurnLeft](v => new TurnLeft(v), _.getDegrees)

我明白了

Error:(x, x) could not find Lazy implicit value of type scodec.Codec[Command]
    val codec: Codec[Either[UnrecognizedCommand, Command]] = discriminatorFallback(unrecognizedCodec, Codec[Command])

如果我制作degrees字段值字段,这一切都有效。我怀疑无形的东西很棘手。我应该怎么做才能让它工作?

演示该问题的示例项目在此处

4

1 回答 1

1

shapelessGeneric是为“case-class-like”类型定义的。对于第一个近似值,case-class-like 类型的值可以被解构为它的构造函数参数,然后可以用来重构一个相等的值,即。

case class Foo ...
val foo = Foo(...)
val fooGen = Generic[Foo]
assert(fooGen.from(fooGen.to(foo)) == foo)

具有单个构造函数参数列表的案例类满足此标准,而没有构造函数参数的公共(惰性)val 或具有匹配apply/的伴侣的类unapply则不满足。

的实现Generic是相当宽松的,并且会将对应于构造函数参数(按类型和顺序)的(惰性) val 成员视为等效于可访问的构造函数参数,因此我们可以获得的最接近您的示例的内容是这样的,

sealed class TurnLeft(degrees: Int) extends Command {
  val getDegrees: Int = degrees
}

scala> Generic[TurnLeft]
res0: shapeless.Generic[TurnLeft]{type Repr = Int :: HNil } = ...

在这种情况下getDegrees,被视为单个Int构造函数参数的访问器。

于 2017-02-06T10:21:54.387 回答