Scala 创建子类型的空IndexedSeq并使用TailRec

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:

接着我的问题,我有一个mergeSort函数,它接受IndexedSeq[a]的子类,并使用merge()函数对其进行排序

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
在这里的唯一用途,无论哪种方式,您都不需要它来做任何其他事情