Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I define a trait with subtraits so their methods only take shared implementation?

Tags:

scala

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
like image 563
Michael Lorton Avatar asked Dec 10 '11 08:12

Michael Lorton


1 Answers

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.

like image 89
Didier Dupont Avatar answered Sep 25 '22 15:09

Didier Dupont