Daryl
Daryl

Reputation: 684

Expression of type Any doesn't conform to expected type_$1

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

Answers (2)

Daryl
Daryl

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

Alexey Romanov
Alexey Romanov

Reputation: 170755

Don't expect the compiler to figure out two existentials are the same, even if they clearly have to be. Workarounds:

  1. Use a type variable pattern:

    list.head match {
      case someB: B[a] => someB.a.value = someB.newValue
    }
    
  2. Extract a method:

    def setValue[A](b: B[A]) = b.a.value = b.newValue
    setValue(someB)
    

Upvotes: 1

Related Questions