yura
yura

Reputation: 14655

Scala generic upper bound

I'm trying to write a simple utility

def withParLevel[T, Col <: ParIterable[T]](coll: Col, ts: TaskSupport): Col = {
  coll.tasksupport = ts
  coll
} 
withParLevel(List(1,2,3,4,5).par, blockingPool)

Which gives me this error:

inferred type arguments [Nothing,scala.collection.parallel.immutable.ParSeq[Int]] do not conform to method withParLevel's type parameter bounds [T,Col <: scala.collection.parallel.ParIterable[T]]

How can I fix that?

Why does it infer T to Nothing, not to Int?

PS scala version 2.10.2

Upvotes: 2

Views: 363

Answers (1)

Sudheer Aedama
Sudheer Aedama

Reputation: 2144

Change the type bound to View Bound. Scala compiler needs evidence between the two type parameters that Col => scala.collection.parallel.ParIterable[T]

Let's have a quick REPL session: (For compilation I did not use the TaskSupport param)

$ scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_05).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.collection.parallel.ParIterable
import scala.collection.parallel.ParIterable

scala> def withParLevel[T, Col <: ParIterable[T]](coll: Col): Col = coll 
withParLevel: [T, Col <: scala.collection.parallel.ParIterable[T]](coll: Col)Col

Let's fix the compilation error using View Bounds:

scala> def withParLevel[T, Col <% ParIterable[T]](coll: Col): Col = coll
withParLevel: [T, Col](coll: Col)(implicit evidence$1: Col => scala.collection.parallel.ParIterable[T])Col

scala> withParLevel(List(1,2,3,4,5).par)
res0: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(1, 2, 3, 4, 5)

Edit: Reason: If one of the type bounds drives the other (in your case, Col derives the inference from T), you would need View Bounds.

Upvotes: 3

Related Questions