Scala upper type bound

550 views Asked by At
class P(name: String)
class E(_name: String, role: String) extends P(_name)

def testF[T <: P](x: List[T]): List[T] = x

val le = List(new E("Henry", "Boss"))
class Test[R <: E](l: List[R]) {
  def r[O <: P] (): List[O] = testF(l)
}

I get:

Error:(8, 38) type mismatch;
 found   : List[R]
 required: List[O]
  def r[O <: P] (): List[O] = testF(l)

My intuition suggests that this should have worked because T has a tighter upper type bound than O.

**** EDIT ****

  def findNN[A, B <: A, C <: A, T] (seq: Seq[B], n: Int, center: C, distance: (A, A) => T)
  (implicit ord: Ordering[T]): Seq[B] = {
    import ord._
    val ds = seq map ( (a: A) => distance(a, center))
    val uds = ds.distinct
    //#TODO: replace quickSelect with median-of algorithm if necessary
    val kel = quickSelect(uds, n)
    val z = seq zip ds
    val (left, _) = z partition Function.tupled((_, d: T) => d <= kel)
    left map {t => t._1}
  }

OK, let's have a look at the example above.

The superclass A provides the method distance. I would like to use the function findNN on a seq[B] having a center in a class C. distance should work because it works on A

Based on feedback provided, there's no way to simplify the type signatures above.

2

There are 2 answers

0
Peter Neyens On BEST ANSWER

You are trying to limit the type of the result using a type parameter R (with an upper bound type E), while you are not using the type R in your function.

An example of a correct use of a type parameter (with an upper bound):

def testF[T <: P](list: List[T]): List[T] = list

testF(List(new P("Tom"))) 
// List[P] = List(P@43bc21f0)
testF(List(new E("Jerry", "Mouse")))
// List[E] = List(E@341c1e65)

An incorrect use of a type parameter:

// does not compile, what is A ??
def foo[A]: List[A] = List("bar")
2
Dmitry  Meshkov On

You made misprinting, you need >: rather then :<

class P(name: String)
class E(_name: String, role: String) extends P(_name)
def testF[T >: P](): List[T] = List(new P("Henry"))