将元组划分为多个元组的类型安全方法 [英] Type-safe way to divide a tuple into multiple tuples
问题描述
我们有一个特性,其中包含一个 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扩展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< :记录](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
}
等。理想情况下,我们希望能够创建类似于
的<$ (会话)=> T1,(会话)=> T2](p2p)
def executePoly2 [T1< ;:记录,T2< ;:记录] ):Tuple2 [T1,T2]
适用于任意元组(即executePoly3,executePoly4等),但有两个问题:
- 有没有办法在这里减少样板数量,或者我们会阻止创建22个不同的方法签名?
- 是否存在一种类型安全的方法来分解类似于
seq的元组.grouped
方法调用,还是我们坚持对所有不同的threadCount
值(目前不超过4)有特殊情况?
您可以通过Miles Sabin使用Shapeless库获得非常容易使用的内容。看看他们可以用元组。
import syntax.std.tuple._
import poly._
var myProducedTuple = myTuple map(_(session))
We have a trait that among other things contains an execute[T <: Record](Seq[(Session) => T]): Seq[T]
method, where Record
is the supertrait of all traits that we're retrieving from the database
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
}
and so on. Ideally we'd like to be able to create something like a
def executePoly2[T1 <: Record, T2 <: Record]
(tuple: Tuple2[(Session) => T1, (Session) => T2]): Tuple2[T1, T2]
for arbitrary tuples (i.e. an executePoly3, executePoly4, etc), but there are two problems:
- Is there a way to reduce the amount of boilerplate here, or would we be stuck creating 22 different method signatures?
- Is there a type-safe way to split up a tuple similar to the
seq.grouped
method call, or are we stuck having special cases for all of the differentthreadCount
values (which at present doesn't exceed 4)?
You can get to something very easy to use using the Shapeless library by Miles Sabin. See what they can do with a Tuple. Specifically abstracting over arity.
import syntax.std.tuple._
import poly._
var myProducedTuple = myTuple map (_(session))
这篇关于将元组划分为多个元组的类型安全方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!