The following code works as (I) expect in scala2 but generates a compile-time error in scala3. I tried to find an explanation in Programming in Scala, Fifth Edition and the web but failed. Any insights?
object Main {
def main(args:Array[String]): Unit = {
val foo = new Foo(7)
println(foo.double) // 14
val bar = new Foo(8) {
def triple:Int = this.i * 3
}
println(bar.double) // 16
println(bar.triple) // 24 in scala2; compile error in scala3
}
}
class Foo(val i:Int) {
def double:Int = i*2
}
Compilation error:
-- [E008] Not Found Error: /tmp/example.scala:12:20 ----
12 | println(bar.triple)
| ^^^^^^^^^^
| value triple is not a member of Foo
If you compile your code with
scala -Xprint:typer, you'll see thatval barnow explicitly has typeFooin Scala 3:Contrast this to Scala 2, where
bargets the refinement typeFoo { def triple: Int }:So, it's
To achieve the behavior of Scala 2, you could introduce a new class
Barexplicitly:Full compilable code:
As for the reason why it's inferring
Fooinstead ofFoo { def triple: Int }- I'm not exactly sure, I guess they just figured out eventually that this behavior plays better with other language features.How would you explain that
val x = "hello"infersx: Stringand notx: "hello"?