sak
sak

Reputation: 3

compile error when defining scala function

I am using scala 2.10.3 and I have the following test code (test.scala) that does not work:

case class Person (name: Name, age: Age)
sealed class Name (val value: String)
sealed class Age (val value: Int)
def foo (n: Name, a: Age): Person = new Person (n, a)

case class PersonBasic (name: String, age: Int)
def fooBasic (n: String, a: Int): PersonBasic = new PersonBasic (n, a)

When I run scalac, I get:

scala> :load test.scala
Loading test.scala...
defined class Person
defined class Name
defined class Age
<console>:31: error: type mismatch;
 found   : Name(in object $iw)(in object $iw)(in object $iw)(in object $iw)
 required: Name(in object $iw)(in object $iw)(in object $iw)(in object $iw)
def foo (n: Name, a: Age): Person = new Person (n, a)
                                                   ^
<console>:31: error: type mismatch;
 found   : Age(in object $iw)(in object $iw)(in object $iw)(in object $iw)
 required: Age(in object $iw)(in object $iw)(in object $iw)(in object $iw)
   def foo (n: Name, a: Age): Person = new Person (n, a)
                                                      ^
defined class PersonBasic
fooBasic: (n: String, a: Int)PersonBasic

Question: Why does fooBasic compile with no problems, but foo doesn't?

I searched for an answer to this question - saw something about tuples, tried it out, but it did not work for me either.

Upvotes: 0

Views: 1062

Answers (1)

om-nom-nom
om-nom-nom

Reputation: 62835

The problem: you have already defined classes Name and Age floating in your REPL session, then you loading your script which define Person (relying on v.1 classes) and then you re-define Name and Age classes, so now REPL have Name and Age v.2, Person still thinks in terms of v1. Boom. They don't fit anymore. Solution -- start a brand new session.

Moreover, to make your script compilable, move Age and Name classes before Person class.

A couple of notes on style:

  1. There is no point of making Name and Age sealed, make them final if you want to disallow inheritance
  2. type aliases will likely do a better job there
  3. case classes should be instantiated without new keyword.

Upvotes: 4

Related Questions