感谢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)
}
}
我现在想开始使用actor在整个群集中的FactoredOut
部分中传播工作。为此,我需要一种方法来传递带有Environment
的不可变消息。
显然以下内容不起作用,但展示了我正在尝试做的事情
object Messages{
case class EvolvePopulation(env: Environment)(prevPopulation: env.Population)
}
传递人口的正确方法是什么?周围的环境是什么?
(会添加dependent-method-types标签,但我没有足够的点来添加'new'标签)
答案 0 :(得分: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)