Hi Jasper,
I’ve been working with your suggested code and having quite some success. Again, thank you.
Just a couple of questions though:
- The following test vector will fail:
case class Baz(a: String, b: String, c: String, d: Option[String])
case class Bar(a: Int, b: String, c: Double, d: String, e: Int, f: Baz, g: Boolean)
case class Foo(s: String, b: Bar, c: Int)
val coll = implicitly[Collect[Foo, String]]
val baz = Baz(“baz-1”, “baz-2”, “baz-3”, Some(“baz-4”))
val bar = Bar(1, “bar-1”, 3.0, “bar-2”, 23, baz, true)
val foo = Foo(“foo-1”, bar, 2)
println(coll(foo))
by only including foo-1 in the resulting list. I ‘fixed’ this by changing genericCollect to include a lazy/value pair like so:
implicit def genericCollect[CC, L <: HList, T](
implicit
gen: Generic.Aux[CC, L],
coll: Lazy[Collect[L, T]]): Collect[CC, T] =
new Collect[CC, T] {
def apply(cc: CC) = coll.value(gen.to(cc))
}
though I cannot say that I feel comfortable with my limited understanding of why this works. In any event, the output is now:
List(foo-1, bar-1, bar-2, baz-1, baz-2, baz-3)
which, of course, is better but lacks the baz-4 which is an Option[String].
Somewhat feeling in the dark I added:
implicit def headIsOptionCollect[CC, L <: HList, T](
implicit
collHead: Collect[CC, T],
collTail: Collect[L, T]): Collect[CC :: L, T] =
new Collect[CC :: L, T] {
def apply(l: Option[CC] :: L) = {
(l.head: Option[CC]) match {
case Some(ll) => collHead(ll) ::: collTail(l.tail)
case None => collTail(l.tail)
}
}
}
and received the compilation error:
[error] /home/ubuntu/Workspac/dev/sbt-scala/test.scala:48: object creation impossible, since method apply in trait Collect of type (cc: CC :: L)List[T] is not defined
[error] new Collect[CC :: L, T] {
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 11 s, completed Aug 24, 2017 12:21:53 PM
and am now somewhat lost …
Any guidance you can give me on this would be very greatly appreciated.
Kind regards, Lawrence