Here is what I am trying to do
class Bar[P](val x: P) { type Foo = P }
class Baz[R <: Bar[_]](bar: R) { val x: R#Foo = bar.x }
The idea is to create Baz
with a single type parameter, and have access to both types inside of it.
But this does not work :(
found : Baz.this.x.type (with underlying type _$1)
required: _$1
It sounds like "underlying type _$1" is exactly what I want here, but that does not compile. Is there a way to do what I want here?
update
Perhaps, I oversimplified the use case.
Let's say, Bar
is actually something like this:
trait Foo[T] { def doStuff(t: T) = ??? }
class Bar[P] extends Foo[P](val x: P) { type Foo = P }
and somewhere else I have a
def fooX[T](x: T, foo: Foo[T]) = foo.doStuff(x)
and I want to call it from Baz
:
class Baz[R <: Bar[_]](bar: R) { fooX(bar.x, bar) }
It feels like it should work: fooX
parameters will always be of the correct type. But it does not compile, and I can't think of a better workaround than to have two type parameters to Baz
, which seems redundant.
When you invoke
fooX(bar.x, bar)
, the compiler sees only:bar: Bar[_]
which is the same asbar : Bar[X] forSome { type X }
bar.x : X forSome { type X }
, which reduces tobar.x: Any
and then it fails to prove that
Any
is the same asX
inforSome { type X }
. However, if you bind the unknown type to a variablep
, then the compiler sees:bar: Bar[p]
bar.x : p
fooX[p](bar.x, bar)
is applicable.Therefore, this works:
Outtakes (pre-update attempts)
Two snippets that attempted to solve the original question, maybe you find something helpful here:
another way to tie
x
toFoo
: