Scala 创建子类型的空IndexedSeq并使用TailRec
接着我的问题,我有一个mergeSort函数,它接受IndexedSeq[a]的子类,并使用merge()函数对其进行排序Scala 创建子类型的空IndexedSeq并使用TailRec,scala,generics,recursion,Scala,Generics,Recursion,接着我的问题,我有一个mergeSort函数,它接受IndexedSeq[a]的子类,并使用merge()函数对其进行排序 def mergeSort[A, Repr <: IndexedSeq[A]] (l: Repr)(implicit ev: Repr => SeqLike[A, Repr], cbf: CanBuildFrom[Repr, A, Repr], ordering:
def mergeSort[A, Repr <: IndexedSeq[A]]
(l: Repr)(implicit ev: Repr => SeqLike[A, Repr],
cbf: CanBuildFrom[Repr, A, Repr],
ordering: Ordering[A]): Repr = {
if (l.length <= 1) l
else {
val (left, right) = l.splitAt(l.length / 2)
merge[A, Repr](IndexedSeq.empty[A], mergeSort(left), mergeSort(right))
}
}
def mergeSort[A,Repr SeqLike[A,Repr],
cbf:CanBuildFrom[Repr,A,Repr],
排序:排序[A]:Repr={
如果(l.length没有完全测试,我不相信这确实实现了您的TailCall目标,但它可以编译
import scala.util.control.TailCalls._
def mergeSort[A :Ordering, C[_]](l: C[A])(
implicit ev :C[A] => SeqLike[A, C[A]],
cbf :CanBuildFrom[C[A], A, C[A]]) :TailRec[C[A]] =
if (l.length <= 1) done(l)
else {
val (left, right) = l.splitAt(l.length / 2)
for {
tcl <- tailcall(mergeSort(left))
tcr <- tailcall(mergeSort(right))
} yield merge(l.drop(l.length), tcl, tcr)
}
导入scala.util.control.TailCalls_
def mergeSort[A:排序,C[]](l:C[A])(
隐式ev:C[A]=>SeqLike[A,C[A]],
cbf:CanBuildFrom[C[A],A,C[A]]:TailRec[C[A]]=
如果(l.length)你能添加merge
的代码吗?请看代码上方的链接l.drop
是cbf()的一个非常有创意的替代品。结果:不是l.drop(l.length)一个O(n)操作吗?至少不应该是IndexedSeq
。l.take(0)
可能是一个更安全的选择。但“正确”的方法是cbf().result
。这将是cbf
在这里的唯一用途,无论哪种方式,您都不需要它来做任何其他事情