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