Reputation: 49705
It's more easily explained in code:
class Bippy {
val x = 42
class Boppy {
val y = "hello world"
}
val bop = new Boppy
}
val bip = new Bippy
val bop: Bippy#Boppy = bip.bop
bop
is then supplied to another method, which needs to find the value x
from the containing instance of Bippy
. What's the magic incantation to do so?
The instance bop
comes from code that I don't control, so adding new methods to Boppy
isn't an option here.
Upvotes: 5
Views: 221
Reputation: 23046
As James said, you can't. His cheat makes my eyes bleed, and I suggest doing something else instead ;-)
I strongly recommend modifying the consumers of bop if you can. Rather than handing them an instance of Bippy#Boppy, hand them a pair comprising the value of the dependent type and the value that the type depends on,
trait DependentPack {
val bippy : Bippy
val boppy : bippy.Boppy
}
val bip = new Bippy
val bop = bip.bop
val dep = new DependentPack { val bippy = bip ; val boppy = bop }
foo(dep)
def foo(dp : DependentPack) = {
import dp._
// use bippy ...
// use boppy ...
}
Note that this is in part a workaround for the lack of dependent method types (enabled in scalac by adding the -Ydependent-method-types or -Xexperimental command line switches). If we had them, then we could drop artefacts like DependentPack and rewrite the above as,
val bip = new Bippy
val bop = bip.bop
foo(bip)(bop)
def foo(bippy : Bippy)(boppy : bippy.Boppy) = {
// use bippy ...
// use boppy ...
}
Needless to say, I think having dependent method types enabled by default would be highly desirable. Non-trivial uses of dependent types bring a world of pain with them in their absence unless you're very careful.
Upvotes: 4
Reputation: 19367
You can't. At least not without cheating. Here's how to cheat.
def getOuter(bop : Bippy#Boppy) =
bop.asInstanceOf[{def Bippy$Boppy$$$outer() : Bippy}].Bippy$Boppy$$$outer()
Obviously that's very dependent on details of how scalac works today and no guarantees that it will work tomorrow.
Upvotes: 7