深层搜索嵌套结构

时间:2016-01-13 08:23:51

标签: scala shapeless

我尝试以与实施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)
  )

}

以下作品:

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)

但是以下没有编译:

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)))
      ^

以下内容也不会使用上述相同的错误消息进行编译:

scala> deepsearch(condition ,11::"30"::Baz("foo",22)::HNil)
scala> deepsearch(condition , (111,222, (111,22, (111, (111, "zoo")))))

我见过类似Weird behavior trying to convert case classes to heterogeneous lists recursively with Shapeless的类似问题,但仍然无法弄清楚它为什么不编译。

那么如何让它编译所有案例呢?

0 个答案:

没有答案