2012-05-26 17 views
6

Gracias a la publicación this me estoy familiarizando con los tipos de métodos dependientes. Tengo una estructura similar a la siguienteMensaje equivalente a los tipos de métodos dependientes

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

ahora quiero empezar a utilizar actores para difundir el trabajo en la parte FactoredOut través de un cluster. Para hacer esto, necesito una manera de pasar mensajes inmutables que llevan el Environment.

Obviamente el siguiente no funciona, pero demuestra lo que estoy tratando de hacer

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

¿Cuál es la forma correcta de pasar la población y del medio ambiente en todo encierra?

(habría añadido la etiqueta dependiente de tipos de métodos, pero no tienen suficientes puntos para agregar una etiqueta de 'nuevo')

Respuesta

6

Su intuición de que usted necesita para empacar tanto el valor del dependiente escriba (env.Population) y el valor del que depende el tipo (env) como un solo objeto es exactamente correcto.

Teniendo en cuenta las definiciones que ya ha publicado, probablemente el enfoque más simple sería algo como esto,

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

Ahora si definimos un tipo de entorno concreto,

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

podemos usarlo directamente como antes,

val e1 = new ConcreteEnvironment 

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

y también podemos empaquetar un entorno y población para distribución,

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

Fantástico, como siempre. No habría seguido esto en absoluto si no hubiera sido por el sistema de tipo inmersión profunda en su curso. – Pengin

Cuestiones relacionadas