Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

+= on a Vector gives strange / wrong type errors

Tags:

scala

I have a variable v that is a Vector, and I'm trying to add an element to it using +=. It complains that it expects a String instead of an Int:

Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> var v = Vector[Int]()
v: scala.collection.immutable.Vector[Int] = Vector()

scala> v += 3
<console>:9: error: type mismatch;
 found   : Int(3)
 required: String
              v += 3
                   ^

Why does it expect a String? When I give it a String (which is ofcourse wrong), it says it expects a Vector[Int]:

scala> v += "three"
<console>:9: error: type mismatch;
 found   : String
 required: scala.collection.immutable.Vector[Int]
              v += "three"
                ^

And when I give it a Vector[Int], it again expects a String:

scala> v += Vector(3)
<console>:9: error: type mismatch;
 found   : scala.collection.immutable.Vector[Int]
 required: String
              v += Vector(3)
                         ^

Why does this happen?

I know I can add an element using +:=. But why can I not use +=, like for a Set?

like image 512
Jesper Avatar asked Dec 27 '13 11:12

Jesper


1 Answers

Let's go through this cases one by one:

scala> v += 3
<console>:9: error: type mismatch;
 found   : Int(3)
 required: String
              v += 3
                   ^

Here is the main problem that Vector have no + method, so compiler will default to string concatination (which is highly criticized recently as a design flaw, by the way). The problem is that left side (vector) is convertible automatically to string (via Vector.toString), but right one is not.

scala> v += "three"
<console>:9: error: type mismatch;
 found   : String
 required: scala.collection.immutable.Vector[Int]
              v += "three"
                ^

Here concatenation is ok, but you're trying to put result of type String to variable of type Vector[Int], which is why compiler complains. But if you define v as Any compiler will stop complaining:

var v: Any = Vector[Int]()
v += "foo"
// res1: Any = Vector()foo

Now, next case

scala> v += Vector(3)
<console>:9: error: type mismatch;
 found   : scala.collection.immutable.Vector[Int]
 required: String
              v += Vector(3)
                         ^

String concatenation again, and again, result of type String goes to the variable of type Vector.

Now, talking about why Vector does not have the very same + operation: ordinary Set have no notion of order, whereas Vector, and Seq in general have and + would be confusing: do I add to the end or to the start? So instead of implicit rule, you have to explicitly decide whether you use :+ or +:.

like image 65
om-nom-nom Avatar answered Oct 16 '22 15:10

om-nom-nom