3

2 つの特性があり、それぞれがそのメンバーの 1 つの型パラメーターを持ちます。最初のトレイトには、2 番目のトレイトのインスタンスと 2 番目のトレイトの型メンバーのインスタンスを受け取る関数があります。この関数は、その型メンバーのインスタンスを期待している 2 番目の特性の関数を呼び出します。ただし、これが実際に機能するように、呼び出しを適切にパラメーター化する方法がわかりません。失敗する簡単な例を次に示します。

trait Garage {
  type CarType <: Car
  def Cars: Seq[CarType]

  def copy(Cars: Seq[CarType]): Garage

  def Refuel(car: CarType, fuel: CarType#FuelType): Garage = {
    val car_index = Cars.zipWithIndex.find(_._1 == car).get._2

    copy(Cars.updated(car_index, car.Refuel(fuel)))
  }
}

trait Car {
  type FuelType <: Fuel
  def Fuel: FuelType

  def copy(Fuel: FuelType): Car

  def Refuel(fuel: FuelType): Car = {
    copy(fuel)
  }
}

trait Fuel

これは次のエラーで失敗します。

error: type mismatch;
 found   : fuel.type (with underlying type Garage.this.CarType#FuelType)
 required: car.FuelType
    copy(Cars.updated(car_index, car.Refuel(fuel)))
                                            ^

そのタイプの に受け入れられる aおよび anyをGarage.Refuel受け入れるように関数を制約するにはどうすればよいですか?CarFuelCar

4

2 に答える 2

7

試す:

def Refuel(car: CarType)(fuel: car.FuelType): Garage = {
于 2012-06-28T00:26:15.647 に答える
4

ダニエルの答えはうまくいきますが、私自身の万能薬のような代替案を指摘したいと思います。私はパス依存型を正しく取得するのにかなり苦労しており、最終的に次の戦略にたどり着きました。追加の型パラメーターを記述する必要があるため、もう少し「醜い」ですが、このアプローチは決して私を失望させませんでした:

trait Garage {
  type CarType <: Car[CarType]  // CarType appears as representation type on the right
  def cars: Seq[CarType]

  def copy(Cars: Seq[CarType]): Garage

  def refuel(car: CarType, fuel: CarType#FuelType): Garage = copy(
    cars.map {  // map is more concise for what you try to achieve
      case `car` => car.refuel(fuel)  // backticks to find the particular car
      case other => other
    })
}

trait Car[C <: Car[C]] {  // add a 'representation type'
  type FuelType <: Fuel
  def fuel: FuelType

  // use 'C' instead of 'Car' everywhere, and qualify the type member with 'C#'
  def copy(fuel: C#FuelType): C

  def refuel(fuel: C#FuelType): C = copy(fuel)
}

trait Fuel

この「表現型」の概念に正式な名前があるかどうかはわかりません (知りたいです)。これを教えてくれた人を調べようとしましたが、見つかりませんでした (少なくともスタックオーバーフローでは)。

于 2012-06-28T01:40:52.390 に答える