Отсутствует scodec.Codec[Command] неявно из-за класса с не значащими полями
Я пытаюсь использовать дискриминаторы в существующем проекте, и что-то не так с моими классами, я думаю.
Рассмотрим этот пример scodec. Если я изменю 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
поле значения поля. Я подозреваю, что с бесформенным это сложно. Что я должен сделать, чтобы это работало?
Пример проекта, который демонстрирует проблему, находится здесь.
1 ответ
Бесформенный -х Generic
определен для "case-class-like" типов. В первом приближении тип, подобный классу случая, - это тип, значения которого могут быть деконструированы до его параметров конструктора, которые затем могут быть использованы для восстановления равного значения, т.е.
case class Foo ...
val foo = Foo(...)
val fooGen = Generic[Foo]
assert(fooGen.from(fooGen.to(foo)) == foo)
Классы case с одним списком параметров конструктора соответствуют этому критерию, тогда как классы, которые не имеют открытых (ленивых) значений для своих параметров конструктора, или компаньон с соответствующим 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
параметр конструктора.