在无形中动态参数化 Poly1 函数 [英] Dynamically parametrize Poly1 function in shapeless

查看:31
本文介绍了在无形中动态参数化 Poly1 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这种情况(精简到基本部分)

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 提出了一个带有 Poly2fold 而不是带有 Poly1map,但我不知道如何在我的情况下使用这个建议.

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.

推荐答案

好的,我终于设法使用 Poly2foldRight 来模拟参数化贴图.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆