scala - 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
。
这可能吗?也许除了Shapeless之外还有其他方法?
解决方案
尝试
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
的太粗糙了。由于您的函数对不同类型的值(即HNil
和H :: 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)
推荐阅读
- c# - XmlException: 名称不以合法字符开头 32 ( ) 第 57 行,第 66 位
- javascript - 我可以在 JSON Stringify 请求中使用 JS 变量作为节点吗?
- c# - 示例应用程序的 Ignite Compute 应用程序结果不正确 - 检查示例
- java - Android:RecyclerView.SetAdapter 导致应用程序崩溃,但没有明显错误
- python - 单击停止按钮后Python中的错误
- amazon-web-services - 使用 ElasticSearch 的 AWS DynamoDB 地理空间查询
- javascript - 弹出firebase通知时应用程序出现故障
- javascript - 如何仅使用 npm 或 yarn 安装项目的对等依赖项?
- amazon-cloudformation - 从名称中获取 TargetGroupArn?
- node.js - Backtest.js“ReferenceError:未定义列表”