0

I don't understand the purpose for the signature of the sorted method within the SeqLike trait:

def sorted[B >: A](implicit ord: Ordering[B]): Repr

More precise, I don't get:

  1. The reason for B>:A
  2. What does Repr mean?

Perhaps you can shed some light on this.

Thanks in advance for the effort in answering!

Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92
Adrian
  • 155
  • 9

3 Answers3

2

[B >: A] means that sorted can be called with any ordering on B, where B is a supertype of A.

I suppose A is the type parameter of the trait itself, i.e.

SeqLike is defined as SeqLike[A, This]. To be exhaustive, as SeqLike[A, +This <: SeqLike[A, This] with Seq[A]]. The This <: SeqLike[A, This] is F-bounded polymorphism.

trait A[T <: A[T]] {} // the type parameter to A must be an A
class C extends A[C] {} // this is how you use it.

The actual return type of SeqLike.sorted is This.

This is useful, because this allows SeqLike's methods to not only return SeqLikes, but also subtypes!

Going back to the simple exemple earlier...

trait Model[T <: Model[T]] {
  def find(id: Int): T = ...
}
class User extends Model[User]
val model: User = new User().find(3) # no need to cast.
Ven
  • 19,015
  • 2
  • 41
  • 61
  • Your answer is momentarily too complicated for my level of understanding. I will get back to it when my Scala comprehension evolve. Please see my comment for Costi to understand my initial question in more detail. Thanks!! I upvoted you but the points are not yet visible because of my limited history and reputation on SO. – Adrian Aug 21 '16 at 17:25
  • No problem :-). Hopefully it'll help someone else in the future! – Ven Aug 21 '16 at 17:59
2
  1. The method takes an implicit Ordering which should be able to handle some supertype of A (hence B >: A). I.e. you should be able to use an Ordering[AnyVal] to compare Int values (as AnyVal is a supertype of Int).
  2. Repr is a type parameter of the SeqLike trait itself (SeqLike[+A, +Repr]) described as "the type of the actual collection containing the elements". This is meant to ensure that methods like sorted will return a collection of the same type (e.g. List.sorted will still be a List).
Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92
0

Here is a simple explanation why B >: A:

Let's consider this class (doesn't compile):

class C[+T] {
  def m(x: T): T = x
}

+T means covariant, i.e. C[Any] is a superclass of e.g. C[Int]. Now ("123" is a String, so it's also Any):

val cInt: C[Any] = new C[Int]
cInt.m("123") // ??? We are supposed to return Int here

In reality:

class C[+T] {
  def m[A >: T](x: A): A = x
}

so (compiler infers A as the nearest common ancestor of Any and String here, which is Any)

val cInt: C[Any] = new C[Int]
cInt.m("123") // Any = 123

Definition of SeqLike: trait SeqLike[+A, +Repr], note +A

Victor Moroz
  • 9,167
  • 1
  • 19
  • 23