I have a library with typeclasses that I am migrating to Scala 3 using shapeless-3. One of my typeclasses is:
trait Parser[T] {
def parse(ctx: Context): (Option[T], Context)
}
where Option[T]
represents an optionally parsed T
and Context
wraps the parsing state (e.g. index in a string)
I define some givens
for primitive and basic types and eventually have to define a defaultGen
for products:
given defaultGen[T](using inst: K0.ProductInstances[Parser, T]): Parser[T] with
def parse(ctx: Context) = ???
What should I replace ???
with? I tried inst.construct
, inst.map
but I am unable to make it work without having the compiler complaining with errors such as:
[error] 399 | def parse(ctx: Context) = inst.construct([t] => (p: Parser[t]) => p.parse(ctx))
[error] | ^
[error] | Found: [t] => (sweet.delights.parsing.Parser[t]) => (Option[t],
[error] | sweet.delights.parsing.Context
[error] | )
[error] | Required: [t] => (sweet.delights.parsing.Parser[t²]) => t²
[error] |
[error] | where: t is a type variable
[error] | t² is a type variable with constraint
Type mismatch means that you should use not construct
. Try unfold
given defaultGen[T](using inst: K0.ProductInstances[Parser, T]): Parser[T] with
def parse(ctx: Context) = inst.unfold[Context](ctx)(
[t] => (c: Context, p: Parser[t]) => p.parse(c).swap
).swap
See other examples: