Constructor type cannot be instantiated to expected type

So I learned something from the book:


class Role
case object Manager extends Role
case object Developer extends Role

case class Person(name: String, age: Int, role: Role)

val alice = new Person("Alice", 25, Developer)
val bob = new Person("Bob", 32, Manager)
val charlie = new Person("Charlie", 32, Developer)

    for (item <- Map(1 -> alice, 2 -> bob, 3 -> charlie)) {
      item match {
  		case(id, p @ Person(_, _, Manager)) => println(p+ " ist überbezahlt")
      case(id, p @ Person(_, _, _)) => println(p+ " ist unterbezahlt")

/*Das in der case-Klausel eingebette p @ PErson(...) prüft die Übereinstimmung mit einer Person innerhalb
eines umschließenden Tupels.
Gleichzeitig binden wir die Person an eine Variable p, die wir für folgende Ausgaben verwenden. */ 

It’s german, sorry for that. :slight_smile:
It is well explained and all… but I was experimenting a bit. I changed 2 lines as follows:

case(p @ Person(_, _, Manager)) => println(p+ " ist überbezahlt")
case(p @ Person(_, _, _)) => println(p+ " ist unterbezahlt")

I get the error message in the title.
The book doesn’t exlain what’s the deal with the id is. It is not a reserved word. Maybe it is obvious, but I am too dense to comprehend this, why the id is necessary.
But then I tried the following:
case(abc, p @ Person(_, , Manager)) => println(p+ " ist überbezahlt")
case(xzy, p @ Person(
, _, _)) => println(p+ " ist unterbezahlt")

It works!

I am now completely puzzled; the “id” seems to be a filler (so it is formated in the right way?).
Anyhow, I would much appreciate if someone could explain this mind and matter to me

EDIT: Some underscores are missing in the last example

When you iterate through a Map, the elements are tuples. So your cases have to be of the form (*, *) for whatever fits in *. The first element is the key in the Map and the second is the value. You can’t leave off the key and try to just get the value, which is what you are doing when you leave off id or some other name there. Note that if you aren’t using it for anything, the first element could be an underscore.

thank you very much, I get it now.
One more question remains, elementary but still…
In this example following << class Role >> the curly brackets are left out ( {…} )

I find it confusing and kinda inconsistent, because I am used to ALWAYS use curly brackets after such as objects and classes, but doing in this example, the compiler does nothing.

If you aren’t going to put anything in the curly braces, why should the language force you to include them? In Java, C++, C#, etc. you have to have curly braces because that is the only way you include data and a constructor to add initial values. In Scala, you can add arguments that work as both members and a constructor.

The top of your example has a class a two objects that don’t have any data. This is a mechanism for creating an algebraic data type in Scala that you might think of as an enum in Java.