Reputation: 2578
I'm trying to use this kind of code:
trait Outer {
type Inner
def f(x:Inner) : Void
}
object test {
def apply(o: Outer, i : Outer#Inner) : Void =
o.f(i)
}
I got an error in the last but one line:
type mismatch; found : i.type (with underlying type Outer#Inner) required: o.Inner
If I change apply's signature to
def apply(o: Outer, i : o.Inner) : Void
then I got an error:
illegal dependent method type
Is it possible to get this piece of code work?
Upvotes: 3
Views: 117
Reputation: 170733
But imo
o.Inner
is much uglyier thanOuter#Inner
. Would you explain, what the point of use former instead of latter? The compiler can do only static checks soo.Inner
should be equalo.type#Inner
which should be (statically) equal toOuter#Inner
. Am I missing something?
Here is the reason. Imagine you had
class Outer1 extends Outer {
type Inner = Int
def apply(i: Int) { ... }
}
class Outer2 extends Outer {
type Inner = String
def apply(i: Int) { ... }
}
Should test.apply(new Outer1, "abc")
compile? Obviously not, since it'll call Outer1.apply(String)
, which doesn't exist. But then, test.apply(new Outer1, 1)
can't compile either (otherwise you are back to path-dependent types) and there is no way to use this apply
at all!
Upvotes: 1
Reputation: 32719
You can take advantage of method dependent types (see What are some compelling use cases for dependent method types? by example). This will require you to use 2 parameter lists:
trait Outer {
type Inner
def f(x:Inner): Unit
}
object test {
def apply( o: Outer )( i : o.Inner) { o.f(i) }
}
Upvotes: 5