Я пытаюсь выяснить, могу ли я преобразовать 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]]
Есть ли какие-либо последствия, которые я могу импортировать?Любой другой способ решения этой проблемы, который не требует перерывов?
редактировать на основе ответа ретронима:
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 может использоваться полностью отдельно.