【发布时间】:2011-03-08 01:51:51
【问题描述】:
我想知道是否可以将List(Vector(1), Vector(2,3)) 转换为Vector(List(1), List(2,3)) 或任何两个可遍历的类。
这是我目前所拥有的:
import collection.generic.CanBuildFrom
import collection.breakOut
import collection.mutable.ListBuffer
def f[A, CC[X] <: Traversable[X], DD[Y] <: Traversable[Y]](outer: DD[CC[A]])
(implicit cbf1: CanBuildFrom[Traversable[_], A, DD[A]],
cbf2: CanBuildFrom[Traversable[_], DD[A], CC[DD[A]]])
: CC[DD[A]] = {
val builder2 = cbf2()
outer.foreach { inner =>
val builder1 = cbf1()
builder1 ++= inner
builder2 += builder1.result
}
builder2.result
}
f(Vector(List(1), List(2,3)))(breakOut, breakOut)
f(ListBuffer(Vector(1), Vector(2,3)))(breakOut, breakOut)
如果我删除breakOuts,它将无法编译:
f(Vector(List(1), List(2,3))) // won't work
找不到参数 cbf1 的隐含值:scala.collection.generic.CanBuildFrom[Traversable[_],Int,scala.collection.immutable.Vector[Int]]
是否有可以导入的隐式?有没有其他不需要breakOuts的方法来解决这个问题?
根据复名的回答进行编辑:
import scalaz.CanBuildAnySelf
def f[A, CC[X] <: Traversable[X] : CanBuildAnySelf,
DD[Y] <: Traversable[Y] : CanBuildAnySelf](outer: DD[CC[A]])
: CC[DD[A]] = {
val builder2 = implicitly[CanBuildAnySelf[CC]].builder[DD[A], DD[A]].apply()
outer.foreach { inner =>
val builder1 = implicitly[CanBuildAnySelf[DD]].builder[A, A].apply()
builder1 ++= inner
builder2 += builder1.result
}
builder2.result
}
很高兴看到 CanBuildAnySelf 上下文绑定可以完全单独使用。
【问题讨论】: