I'm trying to implement deep search differently from the one implemented here.
import shapeless._
object condition extends Poly1 {
implicit def string = at[String] { x =>
if (x contains "o") Some(x)
else None
}
implicit def int = at[Int] { x =>
if (x.toString contains "0") Some(x.toString)
else None
}
}
object deepsearch extends Poly2 {
implicit def element[F <: Poly1, A, R](
implicit elementSearch: poly.Case.Aux[F, A :: HNil, Option[R]]
) = at[F, A]((f, a) => {
elementSearch(a)
})
implicit def hlistlike[F <: Poly1, A, L <: HList, R](
implicit gen: Generic.Aux[A, L]
, ds: poly.Case.Aux[this.type, F :: L :: HNil, Option[R]]
) = at[F, A] { (f, a) =>
ds(f, gen to a)
}
implicit def hnil[F <: Poly1, R]: Case.Aux[F, HNil, Option[R]] =
at[F, HNil]((_, _) =>
None: Option[R]
)
implicit def hcon[F <: Poly1, H, T <: HList, R](
implicit headSearch: Case.Aux[F, H, Option[R]],
tailSearch: Case.Aux[F, T, Option[R]]
): Case.Aux[F, H :: T, Option[R]] = at[F, H :: T]((f, l) =>
headSearch(f, l.head) orElse tailSearch(f, l.tail)
)
}
Following works:
scala> deepsearch( condition , "1" :: "2" :: "3"::"foo" :: HNil)
res0: Option[String] = Some(foo)
scala> val tuple = (11, "1", "2", "srato",(1,2))
tuple: (Int, String, String, String, (Int, Int)) = (11,1,2,srato,(1,2))
scala> deepsearch( condition , tuple )
res0: Option[String] = Some(srato)
scala> deepsearch(condition, (111, (111, (111, (111, "zoo")))))
res0: Option[String] = Some(zoo)
scala> case class Foo(string: String)
defined class Foo
scala> deepsearch( condition , Foo("foo") )
res0: Option[String] = Some(foo)
scala> case class Bar(foo:Foo)
defined class Bar
scala> deepsearch( condition , Bar(Foo("foo")) )
res1: Option[String] = Some(foo)
But following doesn't compile:
scala> case class Baz(ss: String,int:Int)
defined class Baz
scala> deepsearch(condition,(11,Baz("foo",22)))
<console>: diverging implicit expansion for type
shapeless.poly.Case[A$A1203.this.deepsearch.type,shapeless.::
[A$A1203.this.condition.type,shapeless.::[(Int,$A1203.this.Baz),
shapeless.HNil]]] starting with method hcon in object deepsearch
deepsearch(condition,(11,Baz("foo",22)))
^
Following ones also doesn't compile with same error messages above:
scala> deepsearch(condition ,11::"30"::Baz("foo",22)::HNil)
scala> deepsearch(condition , (111,222, (111,22, (111, (111, "zoo")))))
I have seen similiar questions like this Weird behavior trying to convert case classes to heterogeneous lists recursively with Shapeless but still can't figure out why it is not compiling.
So How can I make it compile all cases?