2017-08-23 70 views
4

我想写一个排序函数,它可以处理任何序列并返回传递给该函数的相同序列。所以,我想出了这个解决方案:scala通用排序函数不能与数组一起工作

def qckSrt[U: Ordering, C <: Seq[U]](xs: C with SeqLike[U, C]) 
    (implicit bf: CanBuildFrom[C, U, C]): C = { 
    val n = xs.length 
    val b = bf() 

    if (n <= 1) xs 
    else { 
    val p = xs.head 
    val (left, right) = xs.tail partition { 
     implicitly[Ordering[U]].lteq(_, p) 
    } 
    b ++= qckSrt(left) 
    b += p 
    b ++= qckSrt(right) 
    b.result() 
    } 
} 

所以它的工作原理与列表,向量,arraybuffers ...但它无法与普通阵列的工作:

scala> qckSrt(Array(1, 2, 6, 2, 5)) 
<console>:16: error: inferred type arguments [Int,Any] do not conform to method qckSrt's type parameter bounds [U,C <: Seq[U]] 
     qckSrt(Array(1, 2, 6, 2, 5)) 
     ^
<console>:16: error: type mismatch; 
    found : scala.collection.mutable.ArrayOps.ofInt 
    required: C with scala.collection.SeqLike[U,C] 
     qckSrt(Array(1, 2, 6, 2, 5)) 
      ^
<console>:16: error: No implicit Ordering defined for U. 
     qckSrt(Array(1, 2, 6, 2, 5)) 

有没有办法让这个为阵列工作吗?

+0

为什么要这样做? SeqLike已经有很多排序方法了。 –

+0

只供学习 –

回答

2

您可以用隐式转换替换继承。对于数组,这将使用隐式包装转换和对于已经SeqLike类型,它将使用一个子类型的证据(implicitly[C[U] <:< SeqLike[U, C[U]]]):

import scala.collection._ 
import scala.collection.generic.CanBuildFrom 


def qckSrt[U: Ordering, C[_]](xs: C[U])(implicit 
    bf: CanBuildFrom[C[U], U, C[U]], 
    asSeq: C[U] => SeqLike[U, C[U]] 
): C[U] = { 
    val n = xs.length 
    val b = bf() 

    if (n <= 1) xs 
    else { 
    val p = xs.head 
    val (left, right) = xs.tail partition { 
     implicitly[Ordering[U]].lteq(_, p) 
    } 
    b ++= qckSrt(left) 
    b += p 
    b ++= qckSrt(right) 
    b.result() 
    } 
} 

添加一个“洞”,以一个型C需要U是在呼叫现场适当推断。

相关问题