Open steinybot opened 1 year ago
That's pretty much a limitation of the library. It's assumed that the typeclasses are "regular" in the sense that when deriving for a case class, we need them for all fields and when deriving for a sealed trait we need them for all child classes. The CallByNeed
is there really to support recursion rather than to avoid summoning a typeclass. E.g. for things like case class Nel[A](head: A, tail: Option[Nel[A]])
. But the instances still need to be there for it to compile.
There is one workaround you could use to convert this from a compile time error to a runtime error. You could derive a wrapper typeclass instead:
trait OptionalThing[A] {
def thing: Option[Thing[A]]
}
but then when you're using it, you would have to throw some kind of error when it's missing and you actually need it.
That makes sense now that I think about how it is implemented. You would need to be able to filter the params before that code gets inlined but that isn't possible. The only thing I can think of is if it were implemented as a macro instead then perhaps we could override a method that returns an Expr
for the params.
I think that could work theoretically in Scala 3 with inline - but I think it's a totally new design of the library. Perhaps worth a try but it would be a breaking change.
I'm not sure why this is happening since they ought to be
CallByNeed
but it looks as though type classes are being summoned for case class parameters even if they are not used:Fails to compile with:
Now obviously I wouldn't expect this to work since
Derivation
is not implemented. In my real use case I am only looking at certain fields withinjoin
and was surprised to get this error when I wasn't using the type class for a String parameter.Reproduction: https://github.com/steinybot/bug-reports/tree/magnolia/typeclasses-too-eager