在无形中动态参数化 Poly1 函数 [英] Dynamically parametrize Poly1 function in shapeless
问题描述
我有这种情况(精简到基本部分)
I have this situation (stripped down to the essential parts)
class Foo[L <: HList](columns: L) {
class toRecord(row: Row) extends Poly1 {
implicit def caseColumn[T] = at[Column[T]] { /* map to a record field */ }
}
def asRecord = {
val resultSet: Stream[Row] = // computation to get result set
resultSet.map { row =>
val m = new toRecord(row) // this can't work
columns.map(m)
}
}
}
这不起作用,因为 map
需要一个稳定的标识符而 m
不是.因此,我需要与结果集中的行数一样多的 Poly1 单例对象
.
This doesn't work since map
wants a stable identifier and m
is not.
So I would need as many Poly1 singleton objects
as many rows I have in the result set.
这与此处讨论的问题相同:https://groups.google.com/forum/#!topic/shapeless-dev/P5DXRgnzqkY,但我找不到使这项工作的方法.
This is the same problem discussed here: https://groups.google.com/forum/#!topic/shapeless-dev/P5DXRgnzqkY, but I can't find a way of making this work.
在链接的讨论中,Miles Sabin 提出了一个带有 Poly2
的 fold
而不是带有 Poly1
的 map
,但我不知道如何在我的情况下使用这个建议.
In the linked discussion Miles Sabin proposed a fold
with a Poly2
instead of a map
with a Poly1
, but I can't figure how to use this suggestion in my case.
推荐答案
好的,我终于设法使用 Poly2
和 foldRight
来模拟参数化贴图.
Ok, I finally managed to use a Poly2
with a foldRight
in order to simulate a parametric map.
这是一个获得想法的例子
Here's an example to get the idea
object toRecord extends Poly2 {
implicit def caseColumn[A, B] = at[Column[A], (Row, B)] {
case (col, (row, acc)) =>
val field = doMyThingy(row, col) // "map" `col` to a recordField using `row` as parameter
(row, field :: acc)
}
}
def asRecord[L <: HList, O <: HList](
implicit folder: RightFolder[L, (Row, HNil.type), toRecord.type, (Row, O)]
): Stream[O] = {
val resultSet: Stream[Row] = // computation to get result set
resultSet.map { row => columns.foldRight((row, HNil))(toRecord)._2 }
}
所以这里的技巧"是将参数作为折叠的初始值传递并在计算过程中携带.
So the "trick" here is to pass the parameter as the initial value of the fold and carry it along during the computation.
在计算中,我们使用 row
作为参数(我们的参数映射")对每个元素应用转换,然后我们简单地将它附加到累加器.
Inside the computation we apply a transformation on each element using row
as parameter (our "parametric mapping") and then we simply append it to the accumulator.
完成后,我们最终得到一个包含 row
和映射的 HList
的元组:我们可以简单地丢弃前者 (._2
代码>),我们就可以开始了.
When we're done, we end up with a tuple containing row
and the mapped HList
: we can simply discard the former (._2
) and we're good to go.
这篇关于在无形中动态参数化 Poly1 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!