Equivalent to messages of dependent method types

Thanks to this publication, I get a head over dependent types of methods. I have a structure similar to the following

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

Now I want to start using members to distribute work on the FactoredOut part through the cluster. To do this, I need a way to send immutable messages that the Environment carries.

Obviously, the following does not work, but demonstrates what I'm trying to do

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

What is the right way to transfer populations and the environment?

(I would add a depend-method-types tag, but I don’t have enough points to add a β€œnew” tag)

+6
source share
1 answer

Your intuition that you need to collect both the value of the dependent type ( env.Population ) and the value that the type depends on ( env ) as one object exactly matches.

Given the definitions you already posted, probably the easiest approach would be something like this,

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

Now, if we define a specific type of environment,

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

we can use it directly, as before,

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

and we can also pack the environment and population for distribution,

 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) 
+6
source

Source: https://habr.com/ru/post/916731/


All Articles