0

I'm am trying to use a case class that has one attribute reference another case class. But there are certain conditions where I construct the object that I get strange type errors.

So something like this works fine.

case class Foo(a:Int)
case class Bar(b:Foo, c:Foo)
val t = Bar(Foo(1),Foo(2))
//t: Bar = Bar(Foo(1),Foo(2))

When I nest it into an object, there doesn't seem to be any problem

object w {
    case class Foo(a:Int)
    case class Bar(b:Foo, c:Foo)
}

I can even create an object

val t = w.Bar(w.Foo(1),w.Foo(2))

However, when I try to construct the object from the previously defined Foo, it gives me a crazy type error.

val f = w.Foo(1)
w.Bar(f,f)

// error: type mismatch;
//  found   : w.Foo
//  required: w.Foo
//               w.Bar(f,f)

Any ideas? Scala 2.10.5

2
  • in scala 2.11.7 works fine Commented Oct 3, 2015 at 6:20
  • I cannot reproduce this (on scala 2.10.5) Commented Oct 3, 2015 at 6:59

1 Answer 1

4

This can happen if you try it on the console, while redefine some of the classes.
If you type this in the console:

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Foo(a:Int)
case class Bar(b:Foo, c:Foo)
val t = Bar(Foo(1),Foo(2))

object w {
    case class Foo(a:Int)
    case class Bar(b:Foo, c:Foo)
}

// Exiting paste mode, now interpreting.

defined class Foo
defined class Bar
t: Bar = Bar(Foo(1),Foo(2))
defined module w

scala> val t = w.Bar(w.Foo(1),w.Foo(2))
t: w.Bar = Bar(Foo(1),Foo(2))

scala> val f = w.Foo(1)
f: w.Foo = Foo(1)

scala> w.Bar(f,f)
res1: w.Bar = Bar(Foo(1),Foo(1))

It will work. However, if you then redefine the w object it will fail:

scala> object w {
     |     case class Foo(a:Int)
     |     case class Bar(b:Foo, c:Foo)
     | }
defined module w

scala> w.Bar(f,f)
<console>:14: error: type mismatch;
 found   : w.Foo(in object w)(in object w)(in object w)(in object w)
 required: w.Foo(in object w)(in object w)(in object w)(in object w)
              w.Bar(f,f)

This happen since at w.Bar(f,f) in the second w, it use the w that define on the second type, but the f is define in the first time. Since they are actually different object (same name and properties, but the type itself is different), then it does not fit.
If you will redefine the depend class (f) then it will works:

scala> object w {
     |     case class Foo(a:Int)
     |     case class Bar(b:Foo, c:Foo)
     | }
defined module w

scala> val f = w.Foo(1)
f: w.Foo = Foo(1)

scala> w.Bar(f,f)
res3: w.Bar = Bar(Foo(1),Foo(1))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.