What is the reason that this type of syntax does not compile?

Say I have:

class Class[CC[A, B]] class Thing[A, B <: Int] class Test extends Class[Thing] // compile error here 

I get a compiler error:

types of type arguments (cspsolver.Thing) do not match the expected types of type parameters (type CC) in the Class class. cspsolver.
Type type parameters do not match the expected parameters of type CC: type C bounds <: Int are more stringent than declared boundaries of type B>: Nothing <: Any

However, when I change the code so that it looks like this:

 class Class[CC[A, B]] class Thing[A, B] { type B <: Int } class Test extends Class[Thing] 

It compiles fine. Aren't they functionally equivalent?

+6
source share
2 answers

The reason is given in the compiler message. In Class you expect unlimited CC , and Thing has the limitation that the argument of the second type must be <: Int . One possibility is to add the same restrictions to the Class as in

 class Class[CC[A,B <: Int]] class Thing[A, B <: Int] class Test extends Class[Thing] 
+1
source

Developing Petr Pudlak’s explanation, here’s what I’m guessing : the compiler is trying to combine CC[A, B] with Thing[A, B <: Int] . According to the declaration of B in CC , B top binding of type Any , which is selected to instantiate B It is expected that B in Thing has Int a its top type binding, and the compiler will thus not be able to receive an error message.

This is necessary to maintain the stability of the type system, as shown in the following sketch. Suppose that Thing defines an operation based on the fact that its B <: Int , for example,

 class Thing[A, B <: Int] { def f(b: B) = 2 * b } 

If you declared Class as

 class Class[CC[A,B]] { val c: CC } 

and Test like

 class Test extends Class[Thing] { val t: Thing } 

without a compiler complaint, you can make the next call

 new Test().tf(true) 

which is obviously unsafe.

0
source

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


All Articles