Can Scala identify identifiers between path dependent types?

Sometimes in Scala, I find that I get type mismatches related to path-dependent types, but I can easily speculate that the types actually match. Here is a simple example:

trait Foo { trait Bar } object Main extends App { val foo1 = new Foo { } val foo2 = foo1 def turkle(x: foo1.Bar) {} turkle(new foo2.Bar {}) } 

which gives: "type mismatch found: java.lang.Object with Main.foo2.Bar required: Main.foo1.Bar".

Now, of course, the paths Main.foo1.Bar and Main.foo2.Bar should match, since we wrote val foo2 = foo1 . We can verify this by changing the last line to

 turkle((new foo2.Bar {}).asInstanceOf[foo1.Bar]) 

which compiles and runs without exception.

Can Scala automatically perform this reasoning as follows? If so, how can I do this?

(And if not, are there any prospects for expanding the type system in this direction?)

I note that sometimes Scala seems to carry out such reasoning. Suppose I change trait Foo to object Foo :

 object Foo { trait Bar } object Main extends App { val foo1 = Foo val foo2 = foo1 def turkle(x: foo1.Bar) {} turkle(new foo2.Bar {}) } 

Now everything compiles fine: somehow Scala found out that both Main.foo1.Bar and Main.foo2.Bar really the same as Foo.Bar .

+4
source share
1 answer

Iulian Dragos gave the answer you need in a recent question. The short version is that the compiler does not parse the stream, so in the first example it cannot say that foo1.Bar and foo2.Bar are the same type, since foo1 and foo2 are of type Foo. But in the second example, foo1 is defined as a singleton type Foo.type (subtype of Foo), so everything works as expected.

You can do your first work example by declaring foo2 as a singleton type of foo1:

 val foo2:foo1.type = foo1 

For information on references, see section 3.2.1 of the Scala Language Reference. 2.9.

+5
source

Source: https://habr.com/ru/post/1387629/


All Articles