Why does the annotation for variation lead to the fact that this subtyping relationship should not be inferred using Scala?

In code

sealed trait Node[+T] case class I[C]() extends Node[C => C] def test[A, B](n: Node[A => B]) = n match { case i: I[c] => val cId: c => c = identity _ val ab: A => B = cId } 

Scala gives the error that c => c not A => B Removing variance annotation in Node[+T] resolves the error.

I am puzzled because I believe that if there is a variance annotation, the match i: I[c] should create a rule (c => c) <:< (A => B) , which is all that is needed to compile this line. What am I missing?

+7
types scala covariance pattern-matching
source share
1 answer

Disclaimer: c at runtime is erased and your match will not work correctly. You match on I[_]

In case your Node is invariant, Node[A] is a subclass of Node[B] only if f A=B It makes

n passed test[A, B](n: Node[A => B]) to really be Node[A => B]

If you deviate, if your n matches the pattern I[Something] for any Something , then A and B must be of type Something

In case Node is covariant, due to the definition of Function1[-A,+B] you can call

test[A,B](n) where n is Node[A1 =>B1] , where A1>:A and B1<:B (equation 1)

therefore, if your n matches a I[C] , that means A1 = C and B1 = C

If you replace c with equation 1 , you get C >: A and C<:B (equation 2)

Therefore, the following assignment is no longer valid.

 f: A => B = C => C 

For the left side to be assigned on the right side, we need C => C be Function1[-A,+B]

This means that A >: C and B <: C , but from equation 2 we know that this does not hold (except for the case C = A and C = B, and there is no evidence if your Node is invariant )

0
source share

All Articles