2012-05-26 30 views
6

感謝this後我得到我的頭圍繞依賴方法類型。我有以下相關方法類型的消息相當於

trait Environment{ 
    type Population <: PopulationBase 
    protected trait PopulationBase 

    def evolveUs(population: Population): Population 
} 

object FactoredOut{ 
    def evolvePopulation(env: Environment)(prevPopulation: env.Population): env.Population = { 
     env.evolveUs(prevPopulation) 
    } 
} 

我現在要開始使用演員來傳播工作在一個集羣中的FactoredOut部分類似的結構。爲此,我需要一種方法來傳遞Environment的不可變消息。

顯然下不起作用,但是它展示了什麼,我試圖做

object Messages{ 
    case class EvolvePopulation(env: Environment)(prevPopulation: env.Population) 
} 

什麼是通過人口的正確方法和它的周圍包圍的環境?

(應添加從屬方法類型的標籤,但我沒有足夠的積分以增加一個「新」的標籤)

回答

6

你的直覺,你需要收拾取決於雙方的價值鍵入(env.Population),並將類型依賴於(env)的值作爲單個對象完全正確。

由於您已發佈的定義,可能是最簡單的方法是這樣的,

// Type representing the packaging up of an environment and a population 
// from that environment 
abstract class EvolvePopulation { 
    type E <: Environment 
    val env : E 
    val prevPopulation : env.Population 
} 

object EvolvePopulation { 
    def apply(env0 : Environment)(prevPopulation0 : env0.Population) = 
    new EvolvePopulation { 
     type E = env0.type 
     val env : E = env0 // type annotation required to prevent widening from 
         // the singleton type 
     val prevPopulation = prevPopulation0 
    } 
} 

現在,如果我們定義了一個具體的環境類型,

class ConcreteEnvironment extends Environment { 
    class Population extends PopulationBase 
    def evolveUs(population: Population): Population = population 
} 

我們可以用它直接像以前一樣,

val e1 = new ConcreteEnvironment 

val p1 = new e1.Population 
val p2 = e1.evolveUs(p1) 
val p3 = e1.evolveUs(p2) 

我們還可以打包一個環境和人口分佈,

def distrib(ep : EvolvePopulation) { 
    import ep._ 
    val p4 = env.evolveUs(prevPopulation) 
    val p5 = env.evolveUs(p4) 
    val p6 = env.evolveUs(p5) 
} 

val ep1 = EvolvePopulation(e1)(p3) 

distrib(ep1) 
+0

神奇,一如既往。如果它不適合在你的課程中進行類型系統的深入研究,那麼根本就不會這樣做。 – Pengin