case class A[T](t:T)
case class WrapperA[T](a:A[T], t: T)
val a: A[_] = A(4)
WrapperA(a, 2)
fails with the following error
<console>:15: error: type mismatch;
found : A[_$1] where type _$1
required: A[Any]
Note: _$1 <: Any, but class A is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
WrapperA(a, 2)
how can I make it work?
metaquestion:
does the scala community prefer to post questions like this in contributors.scala-lang.org or at stackoverflow.com?
I had a couple of bad experiences on receiving no question at all on scala questions on stackoverflow (after months), but my scala contributors experience was amazing so far, immediate help)
I don’t think that can work. if T is inferred to Any then A[_] is not a subtype of A[T], if T is inferred to “the same wildcard type that is in the type of a”, then Int is not a subtype of T, so how could this expression typecheck ?
Ok, then I would manage the scope of the existential using pattern matching or maybe by factoring out the code to a polymorphic method. The type alias trick with the existential won’t be portable to dotty, unless I’m mistaken.
Looks like I can’t Normally, you can introduce a type variable in a pattern to “capture the wildcard” (as Java would say) or “open the existential”, which allows you to name the existentially quantified type without saying what it is. This will help when type inference can’t infer the existential.
That’s not actually what’s happening here. There’s simply no connection between where you produce the A and then put it in the WrapperA.
In other words, there’s no way to tell the type checker that a's type is related to Int, which is required for WrapperA(a, 2) to type check.
So, this doesn’t work:
val a: A[_] = A(4)
a match {
case a: A[t] => WrapperA[t](a, 2)
}
This does (but I don’t know if this fits your requirements):
val at: (A[t], t) forSome {type t} = (A(4), 2)
at match { case (a, t) => WrapperA(a, t) } // inside the scope of the match,
// the type checker will introduce one existential that it can use
// for both `a` and `t`