2014-04-01 104 views
1

我有以下的問題:我想有一個「實例」(參數性狀)和「配置」,而後者是由實例類型參數化:參考自類型參數化性狀

trait Kind 
trait Kind1 extends Kind 
trait Kind2 extends Kind 

trait Instance[T <: Kind] { 
    def configuration: InstanceConfiguration[Instance[_]] 
} 

trait InstanceConfiguration[+T <: Instance[_]] { 
} 

class AInstance extends Instance[Kind1] { 
    override def configuration: AConfiguration = ??? 
} 

class AConfiguration extends InstanceConfiguration[AInstance] { 
} 

class BInstance extends Instance[Kind1] { 
    override def configuration: AConfiguration = ??? 
} 

因此,問題是InstanceConfiguration[Instance[Kind2]]不能用作Instance[Kind1]的配置,但是現在它太泛化了,我希望編譯器在BInstance.configuration上發出錯誤。

那麼如何更改實例trait中配置的定義以引用具體類型的具體InstanceConfiguration?

回答

2

你需要使用F-界限的多態。我建議你閱讀the section在Twitter的Scala的學校,但簡單,Instance需要採取具體類型爲類型參數:

trait Kind 
trait Kind1 extends Kind 
trait Kind2 extends Kind 

trait Instance[A <: Instance[A, T], T <: Kind] { 
    self: A => 
    def configuration: InstanceConfiguration[A] 
} 

trait InstanceConfiguration[+T <: Instance[_, _]] { 
} 

class AInstance extends Instance[AInstance, Kind1] { 
    override def configuration: AConfiguration = ??? 
} 

class AConfiguration extends InstanceConfiguration[AInstance] { 
} 

class BInstance extends Instance[BInstance, Kind1] { 
    override def configuration: AConfiguration = ??? 
} 
+0

謝謝,現在我明白了。在你的解決方案中唯一缺失的部分是自我引用('self:A =>'),它可以防止像類BInstance extends Instance [AInstance,Kind1]'' – abatyuk

+0

這樣的聲明,自我類型確實使它更嚴格。你的編輯被拒絕了,但我去了並且做了同樣的改變。 – wingedsubmariner