Scala:递归模式匹配异构列表,获得每个元素的正确类型



我正在尝试做如下的事情,即通过匹配头部和尾部的模式递归处理HList,每次都将头部传递给泛型函数。

import shapeless._
trait MyTrait {
def myFunc[T](x: String => T): Boolean
def iter(myHList: HList, acc: List[Boolean]): List[Boolean] = {
myHList match {
case HNil => acc
case head :: tail => myFunc(head) :: iter(tail, acc)
}
}
}

问题是我从匹配中获得的头部是Any类型,而不是我放入HList的类型。 我希望将 head 作为参数的函数具有正确的类型参数T

这可能吗? 也许除了无形之外还有其他手段?

试试

def iter(myHList: HList, acc: List[Boolean]): List[Boolean] = {
(myHList: @unchecked) match {
case HNil => acc
case (head: Function1[String, _] @unchecked) :: tail => 
myFunc(head) :: iter(tail, acc)
}
}

(第一个@unchecked禁止显示模式匹配不详尽的警告,第二个@unchecked禁止显示由于类型擦除而导致未经检查的泛String的警告(。

或者,您可以更安全地匹配类型。但通常写一个论点只是一个HList而不是具体的A :: B :: ... :: HNil太粗糙了。由于您的函数对不同类型的值(即HNilH :: T(的作用不同,因此这是一个Poly

object iter extends Poly2 {
implicit val nilCase: Case.Aux[HNil, List[Boolean], List[Boolean]] = 
at((_, acc) => acc)
implicit def consCase[A, T <: HList](implicit 
tailCase: Case.Aux[T, List[Boolean], List[Boolean]]
): Case.Aux[(String => A) :: T, List[Boolean], List[Boolean]] =
at { case (head :: tail, acc) => myFunc(head) :: iter(tail, acc) }
}

用法:

def myFunc[T](x: String => T): Boolean = true
iter(((s: String) => s.toUpperCase) :: ((s: String) => s.length) :: HNil, List[Boolean]()) 
// List(true, true)

相关内容

最新更新