2012-05-26 7 views
6

Dank this Post bekomme ich mich über abhängige Methodentypen her. Ich habe eine Struktur ähnlich der folgendenNachrichtenäquivalent von abhängigen Methodentypen

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) 
    } 
} 

Ich möchte jetzt mit Schauspieler beginnen die Arbeit in der FactoredOut Teil über einen Cluster zu verbreiten. Um dies zu tun, brauche ich einen Weg, um unveränderliche Nachrichten zu übergeben, die die Environment tragen.

Offensichtlich die folgenden nicht funktioniert, zeigt aber, was ich versuche

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

zu tun Was ist der richtige Weg, um die Bevölkerung zu passieren und es Umgebung umschließt um?

(Würde den abhängigen-Methode-Typen-Tag hinzugefügt hat, aber ich habe nicht genug Punkte, einen ‚neuen‘ Tag hinzuzufügen)

Antwort

6

Ihre Intuition, die Sie benötigen sowohl den Wert der abhängigen einpacken Geben Sie (env.Population) ein und der Wert, von dem der Typ abhängt (env), als ein einzelnes Objekt ist genau richtig.

den Definitionen Sie bereits gebucht haben, wahrscheinlich der einfachste Ansatz so etwas wie dieses,

// 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 
    } 
} 

Jetzt

wäre, wenn wir einen konkreten Umwelt-Typ,

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

können wir es definieren verwenden direkt wie zuvor,

val e1 = new ConcreteEnvironment 

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

und wir können auch eine Umgebung und Bevölkerung für den Vertrieb,

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

Fantastisch, wie immer. Wäre das überhaupt nicht gewesen, wenn das Typensystem nicht tief in Ihren Kurs eingetaucht wäre? – Pengin