2017-08-23 17 views
4

どのシーケンスでも動作するソート関数を作成しようとしていますが、この関数に渡されるのと同じシーケンスを返します。だから私はこの解決策を考え出した:だから、リスト、ベクトル、arraybuffersで動作しますscala generic sort関数は配列では機能しません

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() 
    } 
} 

...しかし、それは通常の配列で動作するように失敗します。

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ために必要とされますコールサイトで適切に推測されます。

関連する問題