Scala Set.contains does not give the expected type mismatch error

I'm new to Scala, and I'm afraid to understand why sometimes I don't get a type error when delivering the wrong Set.contains argument

The following is a brief example of using REPL (2.9.1.final):

 scala> val baz = Map("one" -> 1, "two" -> 2) baz: scala.collection.immutable.Map[java.lang.String,Int] = Map(one -> 1, two -> 2) scala> baz.values.toSet.contains("asdf") res3: Boolean = false 

Why didn’t I get type mismatch there?

If I assign baz.values.toSet another val and call contains on this, I get a type check:

 scala> val bling = baz.values.toSet bling: scala.collection.immutable.Set[Int] = Set(1, 2) scala> bling.contains("asdf") <console>:10: error: type mismatch; found : java.lang.String("asdf") required: Int bling.contains("asdf") ^ 

Stupid mistake, language subtlety or compiler error?

+7
source share
1 answer

OK, so Set is invariant in its type parameter and works exactly the same as

 scala> Set(1, 2, 3) contains "Hi" <console>:8: error: type mismatch; found : java.lang.String("Hi") required: Int Set(1, 2, 3) contains "Hi" ^ 

But as you say:

 scala> Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet contains "Hi" res1: Boolean = false 

The only conclusion we can come to is that the type of Set not Set[Int] . What happens if we explicitly say scala, we want Set[Int] ? The same piece of code with an explicit parameter type works just fine (i.e., it does not compile):

 scala> Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet[Int] contains "Hi" <console>:8: error: type mismatch; found : java.lang.String("Hi") required: Int Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet[Int] contains "Hi" ^ 

The problem is that the parameter of the intended type is passed to the toSet method. scala obviously takes into account contains "Hi" and prints lub Int and String (i.e. Any )

+12
source

All Articles