My meta-question would be "How do I ask this question intelligibly?" but perhaps an example would make it clearer:
trait Toolbox {
trait Bolt
trait Wrench {
def tighten(b : Bolt)
}
def getWrench : Wrench
def getBolt : Bolt
}
object MetricToolbox extends Toolbox {
...
}
object EnglishToolbox extends Toolbox {
...
}
Of course, a metric wrench can only tighten a metric bolt; ditto for tools from the English toolbox. My question is, how do I express that in a type-safe way so the following won't compile:
MetricToolbox.getWrench tighten EnglishToolbox.getBolt
but the following will:
def doTighten(box : Toolbox) = box.getWrench tighten box.getBolt
I know for a fact that this is possible because I heard Martin Odersky say it with his own mouth at the Scala meetup last night but at that moment, my wife called my cell and I had to scurry out of the room before he explained how.
EDIT didierd pointed out that my code worked as written. He's right -- I'm a little unclear on the details but it does. The natural reverse questions is, how do I not do that? The answer was pretty simple: put those classes at the same level as the main trait.
trait Nail
trait Hammer {
def pound(n : Nail)
}
trait Toolbox {
trait Bolt
trait Wrench {
def tighten(b : Bolt)
}
def getWrench : Wrench
def getBolt : Bolt
def getNail : Nail
def getHammer : Hammer
}
MetricToolbox.getHammer pound EnglishToolbox.getNail // this DOES compile
As written, it already works. As Bolt and Wrench are nested inside Toolbox, the Bolt that types the argument of tighten means a Bolt of this exact toolbox, not a Bolt of any toolbox. They are written respectively someToolbox.Bolt, which means a Bolt of the exact instance someToolBox and Toolbox#Bolt, which means the Bolt defined in the type Toolbox, whatever the insatance toolbox. So Toolbox#Bolt is a common supertype of all x.Bolt.
Here Bolt without qualification means this.Bolt, this being the enclosing Toolbox. So you cannot mix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With