Adding scala maps inside a loop and conditional statement

I get the error message "error: type arguments [Any]] does not match the sign of restrictions of type Cloneable type [+ A <: AnyRef]," which I cannot do with heads or tails.

In particular,

var M = mutable.Map[Int, mutable.Set[Int]]() for(i <- 1 to 100; j <- 1 to 100) { if(!M.contains(i)) {M += i -> mutable.Set[Int](j)} else {M(i) += j} } 

(I'm actually trying to do something more complex, but this is an error generation code that has been modified and simplified to a minimum)

And the last line of the above code generates an error message. If I take it further

 for(i <- 1 to 100; j <- 1 to 100) { if(!M.contains(i)) {M += i -> mutable.Set[Int](j)} } 

it works!

How to make the code above?

+6
source share
2 answers

Digal diagnosed the problem (it was not possible to unify the types of if-else branches), and this seems like a compiler error. Here's another simplified case that will give an error in REPL after a long compilation time,

 if (true) { null: collection.mutable.Map[Int, Int] } else { null: collection.mutable.Set[Int] } 

In the meantime, you can get your code to compile with an explicit type that was sprinkled somewhere in the if-else statement,

 for(i <- 1 to 100; j <- 1 to 100) { if(!M.contains(i)) {M += i -> mutable.Set[Int](j)} else {M(i) += j}: Unit } 

I asked a question here: https://issues.scala-lang.org/browse/SI-4938

+7
source

I have further reduced your example:

 scala> if(!M.contains(1)) {M += 1 -> mutable.Set[Int](1)} else {M(1) += 1}; <console>:9: error: type arguments [Any] do not conform to trait Cloneable type parameter bounds [+A <: AnyRef] val res17 = ^ 

The problem occurs when the compiler tries to find a common return type for both branches: First -

 scala> M += 1 -> mutable.Set[Int](1) res19: scala.collection.mutable.Map[Int,scala.collection.mutable.Set[Int]] = ... 

And the "else" part

 scala> M(1) += 1 res18: scala.collection.mutable.Set[Int] = Set(1) 

If I add the return value to the end of this expression, REPL eats it without errors:

 scala> if(!M.contains(1)) {M += 1 -> mutable.Set[Int](1)} else {M(1) += 1}; println("hello") hello 

Because the type of the return expression is Unit.

+6
source

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


All Articles