I have this situation (stripped down to the essential parts)
class Foo[L <: HList](columns: L) {
class toRecord(row: Row) extends Poly1 {
implicit
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.
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.
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.