7

スレッド数をパラメーターとして指定して、をに変換するこの関数があります。ArrayParArray

def parN[T](collection: Array[T], n: Int) = {
    val parCollection = collection.par
    parCollection.tasksupport = new ForkJoinTaskSupport(
      new concurrent.forkjoin.ForkJoinPool(n))
    parCollection
}

今、私はこれをジェネリックにして、以外のコレクションで動作するようにしたいと思いますArray:

def parN[S, T[S] <: Parallelizable[S, ParIterable[S]]](collection: T[S], n: Int) = {
    val parCollection = collection.par
    parCollection.tasksupport = new ForkJoinTaskSupport(
      new concurrent.forkjoin.ForkJoinPool(n))
    parCollection
}

しかし、で呼び出すとparN(Array(1, 2, 3), 2)次のエラーが発生します。

inferred type arguments [Int,Array] do not
conform to method parN's type parameter bounds
[S,T[S] <: scala.collection.Parallelizable[S,scala.collection.parallel.ParIterable[S]]]

一方、これは機能しています:

val x: Parallelizable[Int, ParIterable[Int]] = Array(1, 2, 3)

私の型パラメータで何が間違っているのでしょうか?

4

1 に答える 1

5

まず、これは に固有の問題であることに注意してArrayください。メソッドは、Listまたは他の通常のコレクションに対して機能します (複数の型パラメーターを持つもの、または何もないものを除く)。例:

scala> parN(List(1,2,3), 2)
res17: scala.collection.parallel.ParIterable[Int] = ParVector(1, 2, 3)

scala> parN(Set(1,2,3), 2)
res18: scala.collection.parallel.ParIterable[Int] = ParSet(1, 2, 3)

Arrayコレクションに関しては、常に特殊なケースです。なぜなら...それはコレクションではないからです。Java のため、その定義はfinal class Array[T] extends Serializable with Cloneable. Arrayただし、コレクション型 (ArrayOpsおよび) に変換できる、どこでも使用できる 2 つの暗黙型が存在しますWrappedArray。そして、これらの型は を実装Parallelizableするので、すべて問題ないはずです...型推論が邪魔になることを除いて:

型パラメーターは としてのみ定義されてT[S]いるため、 を受け取るとArray[Int]、喜んで を推測Array[Int]し、境界をチェックします: 失敗、Array拡張しませんParallelizable。ゲームオーバー。

2 つのオプションが表示されます。

  • が欲しいと明示的に言うことができますParallelizable

    def parN[S](collection: Parallelizable[S, ParIterable[S]], n: Int)
    

    または、実際の型にアクセスする必要があるT場合 (あなたの場合はいいえですが、誰が知っていますか):

    def parN[S, T[S] <: Parallelizable[S, ParIterable[S]]](collection: T[S] with
       Parallelizable[S, ParIterable[S]], n: Int)
    
  • Parallelizableまたは、暗黙的なパラメーターを使用して、暗黙的に に変換できるものなら何でも受け入れることができます。

    def parN[S, T <% Parallelizable[S, ParIterable[S]]](collection: T, n: Int)
    

    これは、次の短いバージョンです。

    def parN[S, T](collection: T, n: Int)(implicit ev: T => 
      Parallelizable[S, ParIterable[S]])
    

それらはすべて機能するはずです。あなたの場合、最初のものをお勧めします。それは、仕事をする最も読みやすいものです。

于 2013-05-24T13:07:22.727 に答える