Reputation: 684
I have problems with undestanding Scala's type system.
class A[T](var value: T)
class B[T](val a: A[T], var newValue: T)
val list = new MutableList[B[_]]()
val a: A[Int] = new A(10)
val b: B[Int] = new B(a, 11)
list += b
val someB = list.head
someB.a.value = someB.newValue
And after compile i see the error:
Error:(12, 24) type mismatch;
found : A$A36.this.someB.newValue.type (with underlying type _$1)
required: _$1
someB.a.value = someB.newValue
^
Both someB.a.value
and someB.newValue
have the same type but Scala's compiler actually doesn't think so. How this error can be fixed ?
Upvotes: 3
Views: 11480
Reputation: 684
One of solutions I have found is to eliminate usage of existential type with abstract types.
class A[T](var value: T)
abstract class B {
type T
val a: A[T]
val newValue: T
}
val list = new mutable.MutableList[B]()
val aa = new A(10)
val b = new B {
type T = Int
val a = aa
val newValue = 11
}
list += b
val someB = list.head
someB.a.value = someB.newValue
Upvotes: 0
Reputation: 170755
Don't expect the compiler to figure out two existentials are the same, even if they clearly have to be. Workarounds:
Use a type variable pattern:
list.head match {
case someB: B[a] => someB.a.value = someB.newValue
}
Extract a method:
def setValue[A](b: B[A]) = b.a.value = b.newValue
setValue(someB)
Upvotes: 1