0

Such as List.contains ,here is the source code from scala api.

 def contains[A1 >: A](elem: A1): Boolean = { var these = this while (!these.isEmpty) { if (these.head == elem) return true these = these.tail } false 

I understand the inter code theory, But what's about type A1 >: A ?

I guess >: just like isInstanceOf or something like to limit the input param's type?

Could some one give a concise explanation or some docs so i can get some research

2 Answers 2

3

The meaning:

A1 is the nearest common ancestor of A and supplied argument type.

The purpose:

since List is declared as List[+A] where +A means "covariant on type A", using A as an argument type is not allowed:

scala> :pa // Entering paste mode (ctrl-D to finish) class List[+A] { def m(x: A) = x } // Exiting paste mode, now interpreting. <console>:15: error: covariant type A occurs in contravariant position in type A of value x def m(x: A) = x 

UPDATE

Naive explanation why not (just a guess, it's hard to prove since compiler won't allow it):

class List[+A] { def m(x: A) = x } class Fruit class Apple extends Fruit class Pear extends Fruit // list is covariant, which means // List[Fruit] is a supertype of List[Apple] val l: List[Fruit] = new List[Apple] // i.e. l.m has to accept Fruit l.m(new Pear) // Apple? 

in reality:

class List[+A] { def m[A1 >: A](x: A1) = x } ... l.m(new Pear) // Fruit, the nearest common ancestor of Apple and Pear 
Sign up to request clarification or add additional context in comments.

9 Comments

I was puzzled by the contains method signature vis a vis its behaviour of accepting an argument of any type whatsoever. So, the contains method is not type safe. Was there no way for the designers to make the contains method type safe?
Why isn't it type safe? In my last example what is returned is not Object, it's the nearset common ancestor of Pear and Apple. So it's not any type.
Lets say val ls: List[Int] = List(1,2,3,4). Now according to the contains method signature the argument of type A1 has to be a super type of Int. But, we can pass an argument of any type whatsoever to contains and the compiler doesnt complain. This is confusing to me.
So what's wrong? List[Int] is a subtype of List[Any], so if you call List(1).contains(new Pear) it's a valid call (the result is obviously false). Both 1 and new Pear are instances of Any, so you can apply ==.
I might be missing something obvious here. If we have a List[Int] then the A in the contains signature is an Int. And the signature says that A1 has to be Int or a supertype of Int. But, this constraint is not holding, since I am able to pass an argument of any type to the contains method; Whats the point of having that lower bound type constraint if its allowing any type to be passed as an argument?
|
0

A >: B means B is the lower type bound of A

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.