我正在试图弄清楚我是否可以通用方式将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上下文绑定可以完全单独使用,真是令人印象深刻。
答案 0 :(得分:5)
我们在Scalaz中完成它,所以它当然是可能的。
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> List(Vector(1, 2, 3)).sequence
res1: scala.collection.immutable.Vector[List[Int]] = Vector(List(1, 2, 3), List(1, 2, 3), List(1, 2, 3))
scala> Seq(List(1), List(3)).sequence
res2: List[Seq[Int]] = List(List(1, 3))
scala> Vector(ArraySeq(1, 2, 3)).sequence
res3: scala.collection.mutable.ArraySeq[scala.collection.immutable.Vector[Int]] = ArraySeq(Vector(1, 2, 3), Vector(1, 2, 3), Vector(1, 2, 3))
我们只考虑表现良好的&#39;集合,即可以包含任意元素类型的集合,与BitSet
不同。这与https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/CanBuildAnySelf.scala
答案 1 :(得分:0)
这有效:
val l = List(Vector(1), Vector(2, 3))
val v = Vector((for (v <- l) yield v.toList): _*)