类型安全的方式将一个元组分成多个元组

3

我们有一个特质,在其中包含一个execute[T <: Record](Seq[(Session) => T]): Seq[T]方法,其中Record是我们从数据库检索的所有特质的超特质。

trait DbTrait {
  val threadCount: Int
  val db: Database
  protected def getGroupSize(size: Int, threadCount: Int) {
    (size / threadCount) + if(size % threadCount == 0) 0 else 1
  }
  def execute[T <: Record](funs: Seq[(Session) => T]): Seq[T]
}

trait DbTraitSingle extends DbTrait {
  val threadCount = 1
  def execute[T <: Record](funs: Seq[(Session) => T]): Seq[T] =
    db.withSession{session: Session => funs.map(f => f(session))}
}

trait DbTraitMulti extends DbTrait {
  val threadCount = 4
  def execute[T <: Record](funs: Seq[(Session) => T): Seq[T] =
    funs.grouped(getGroupSize(funs.size, threadCount)).map(funs => Future {
      db.withSession{session: Session => funs.map(f => f(session))}
    }.toList.flatten
}

等等。理想情况下,我们希望能够创建类似于

的东西。

def executePoly2[T1 <: Record, T2 <: Record]
  (tuple: Tuple2[(Session) => T1, (Session) => T2]): Tuple2[T1, T2]

对于任意的元组(例如executePoly3、executePoly4等),但存在两个问题:

  1. 有没有办法减少样板代码的量,或者我们将被迫创建22个不同的方法签名?
  2. 是否有一种类型安全的方式来拆分元组,类似于seq.grouped方法调用,或者我们被困在为所有不同的threadCount值(目前不超过4)编写特殊情况的境地中?
1个回答

1
你可以通过Miles Sabin的Shapeless库轻松地使用某些东西。看看他们可以通过Tuple做什么。具体来说,是通过抽象化处理元数。
 import syntax.std.tuple._
 import poly._

 var myProducedTuple = myTuple map (_(session))

谢谢wheaties,抱歉我的无知,但是shapeless的语法让我有点困惑——看起来我需要将元组转换为HList,应用多态映射函数,然后将结果HList转换回元组(或者依赖我的调用者为我执行HList转换)。然而,示例多态函数的形式为例如Set~>Option,而我需要像Session~>T这样的东西,其中Session是不变类型,但我很难找到一个具有裸T的多态函数的示例——它们都包装在OptionSet等中。 - Zim-Zam O'Pootertoot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接