shapeless-guide icon indicating copy to clipboard operation
shapeless-guide copied to clipboard

genericObjectEncoder does not work

Open khanetor opened this issue 7 years ago • 2 comments

The implicit function genericObjectEncoder does not work with Coproduct as descibed in the book.

The current definition is as followed:

implicit def genericObjectEncoder[A, H <: HList](
                                                    implicit
                                                    gen: LabelledGeneric.Aux[A, H],
                                                    hEncoder: Lazy[JsonObjectEncoder[H]]
                                                  ): JsonEncoder[A] =
    createObjectEncoder(value => hEncoder.value.encode(gen.to(value)))

To make this work, I have to remove <: HList.

I do not know why this is the case, but I would love to find out more about it.

Other users reported knownDirectSubclasses bug, but I do not see this error message.

khanetor avatar May 29 '17 23:05 khanetor

As I mentioned on gitter, the reason for this is that the LabelledGeneric for A could either be an HList (for case class), or a Coproduct of HLlists if A is a sealed trait with subclasses. We want genericObjectEncoder to work for both, but implicit resolution will neglect to consider it for a Coproduct, because of the H <: HList constraint. Removing it does the trick.

I agree that the book should be amended, I'm happy to make a PR with a small paragraph, but I'm not too sure who the maintainers for this project are, and if they're accepting pull requests.

The knownDirectSubclasses is unrelated to the code in the example, it appears in random cases whenever you try to derive a LabelledGeneric. I think the problem is only definitely solved by enum in Dotty.

SystemFw avatar Jun 02 '17 13:06 SystemFw

@SystemFw hit the nail on the head -- the <: HList annotation shouldn't be there. I'll incorporate this correction in next time I fold errata into the book.

davegurnell avatar Jun 05 '17 11:06 davegurnell