6

この投稿のおかげで、私は依存メソッドの型について頭を悩ませています。私は次のような構造を持っています

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

人口を通過させる正しい方法は何ですか?周囲の環境を囲んでいますか?

(dependent-method-types タグを追加する必要がありましたが、「新しい」タグを追加するのに十分なポイントがありません)

4

1 に答える 1

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)
于 2012-05-26T10:57:52.953 に答える