Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Map and Set aliased in scala.Predef?

Tags:

scala

9 times out of 10, simply using Map and Set behave like I expect they would, but occasionally I am unexpectedly hit with

error: type mismatch; 
[INFO]  found   : scala.collection.Set[String]
[INFO]  required: Set[String]

As an example, from the REPL:

scala> case class Calculator[+T](name: String, parameters: Set[String])
defined class Calculator

scala> val binding=Map.empty[String, String]
binding: scala.collection.immutable.Map[String,String] = Map()

scala> Calculator("Hello",binding.keySet)
<console>:9: error: type mismatch;
found   : scala.collection.Set[String]
required: Set[String]
       Calculator("Hello",binding.keySet)
                                  ^

I think I understand the error, that is, the function call on the aliased types return the actual types.

And so it seems to me the solution is to import the un-aliased types. Upon which every other file in my project will now generate type mismatch errors, so I will have to import it in each file. Which leads to the question I ask in the title -- what was the purpose of the alias in Predef, if eventually I need to import the actual package anyway?

Is my understanding flawed, or is my use case not the typical one, or both?

like image 443
Jim Avatar asked Nov 15 '10 17:11

Jim


2 Answers

You have misdiagnosed the problem. It isn't that it doesn't recognize the type alias is the same type as what it is aliasing. It's that the type alias is scala.collection.immutable.Set and that is not the same as scala.collection.Set.

Edit: by the way, I thought I'd fixed this, as evinced by the comment in the type diagnostics:

   ... Also, if the
*  type error is because of a conflict between two identically named
*  classes and one is in package scala, fully qualify the name so one
*  need not deduce why "java.util.Iterator" and "Iterator" don't match.

Apparently needs more work.

Edit 7/17/2010: OK, it took me a shockingly long time, but now at least it says something hard to misunderstand.

files/neg/type-diagnostics.scala:4: error: type mismatch;
 found   : scala.collection.Set[String]
 required: scala.collection.immutable.Set[String]
  def f = Calculator("Hello",binding.keySet)
                                     ^
like image 194
psp Avatar answered Nov 03 '22 11:11

psp


The real problem is that scala.collection.immutable.Map#keySet returns a scala.collection.Set (a read-only Set) instead of a scala.collection.immutable.Set (an immutable Set). I'll leave it for someone else to explain why that is...

Edit

Someone asks for an explanation for the return type of Map#keySet in this thread, but doesn't get an answer.

like image 43
Ben Lings Avatar answered Nov 03 '22 11:11

Ben Lings