【发布时间】:2020-01-01 08:43:25
【问题描述】:
我正在尝试实现一种对调用者提供的 HList 进行参数化折叠的方法。 HList 可以有任意数量的相同类型的元素 (> 0)。
val list = "a" :: "b" :: "c" :: HNil
def process[L <: HList](mul: Int, l: L) = {
object combine extends Poly2 {
implicit def work = at[String, (Int, L)] {
case (a, (b, acc)) => (b, (a * b) :: acc)
}
}
l.foldRight((mul, HNil))(combine)._2
}
process(3, list) // expecting to get aaa :: bbb :: ccc :: HNil
我得到的是关于缺少隐式的错误:“找不到参数文件夹的隐式值:shapeless.ops.hlist.RightFolder[L,(Int, shapeless.HNil.type),combine.type]”。从this answer 可以清楚地看出,编译器希望看到它可以折叠 HList 的证据。
但是我不能将 RightFolder 作为隐式参数传递,因为 Poly2 类型在方法之外是未知的。即使有可能,隐式参数也只会在调用堆栈中进一步向上传播。事实上,我什至不希望调用者知道该方法是否执行折叠、映射、归约或其他任何操作。它需要提供的只是 HList 是正确的 HList 类型的证据。我认为问题在于 [L <: hlist>
以下代码按预期工作,但显然没有将折叠逻辑封装在方法中:
val list = "a" :: "b" :: "c" :: HNil
object combineS extends Poly2 {
implicit def work[L <: HList] = at[String, (Int, L)] {
case (a, (b, acc)) => (b, (a * b) :: acc)
}
}
list.foldRight((3, HNil))(combineS)._2
【问题讨论】:
标签: scala implicit shapeless hlist