Scala upper and lower bounds

Consider the following hierarchy:

class C1
class C2 extends C1
class C3 extends C2
class C4 extends C3

I want to write a function that just accepts C2and types C3. For this, I thought of the following:

 def f [C >: C3 <: C2](c :C) = 0

I expect the following behavior

f(new C1)  //doesn't compile, ok
f(new C2)  //compiles, ok
f(new C3)  //compiles, ok
f(new C4)  // !!! Compiles, and it shouldn't 

The problem is calling with C4, which I do not want to resolve, but the compiler accepts. I understand what C4 <: C2is right and what C4can be considered as C3. But when specifying a border, [C >: C3 <: C2]I would expect the compiler to find Cone that will evaluate both borders at the same time, and not one by one.

Question: is there a way to achieve what I want, and if not, does the compiler try to avoid some inconsistency with this?

: , . C4 C >: C3, . - C3 <:< C.

+4
2

, . :

def f[C <: C2](c: C)(implicit ev: C3 <:< C) = 0

f(new C4) .

, , , :

val c: C3 = new C4
f(c)

c C3, , C4 .

, , Failure(...) None

+10

, _ :

S > : T , S, T , S. , T, T.

, , . : f:

def f[U >: C3 <: C2](c: U) = c

:

 val a2 = f(new C2)
 val a3 = f(new C3) 
 val a4 = f(new C4) 
 List[C2](a2, a3, a4)  //compiles
 List[C3](a3, a4)  //compiles
 List[C4](a4)  //does not cause a4 is C3

, .

+4

Source: https://habr.com/ru/post/1599494/


All Articles