0

これは前の質問のフォローアップGarageであり、型メンバーを持つ特性がありCarType、それ自体が型メンバーを持っていて、最初の引数としてのインスタンスと最初の引数のインスタンスを取ることができるFuelType関数が必要でした2番目の引数。refuelCarTypeFuelType

答えは、以下の2つの特性でありCar、表現タイプを指定することでしたC <: Car[C]。私が今抱えている問題は、実装している具象クラスで型パラメーターを定義する方法がわからないことです。Garageたとえば、ConcreteGarage以下のようになります。

trait Fuel

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

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

  def refuel(car: CarType, fuel: CarType#FuelType): Garage = copy(
    cars.map {
      case `car` => car.refuel(fuel)
      case other => other
    })
}

trait Car[C <: Car[C]] {
  type FuelType <: Fuel
  def fuel: FuelType

  def copy(fuel: C#FuelType): C

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

class ConcreteGarage(val cars: Seq[ConcreteGarage#CarType]) extends Garage {
  type CarType = Car[CarType] // Nope
  //type CarType = Car[Any] // Nope
  //type CarType = Car[Nothing] // Nope
  //type CarType = Car[Car] // Nope
  //type CarType <: Car[CarType] // Nope
  def copy(cars: Seq[CarType]) = new ConcreteGarage(cars)
}
4

1 に答える 1

1

だから私はあなたの人生の残りのために別のタイプのパラメータを持ち歩かなければならないという醜いことに注意すると言いました:)

class ConcreteGarage[C <: Car[C]](val cars: Seq[C]) extends Garage {
  type CarType = C
  def copy(cars: Seq[C]) = new ConcreteGarage(cars)
}

もちろん、特定のガレージがある場合はもっと簡単です。

case class Benzin(litres: Int) extends Fuel
case class Mustang(fuel: Benzin) extends Car[Mustang] {
   type FuelType = Benzin
   def copy(fuel: Benzin) = Mustang(fuel)
}
case class MustangGarage(cars: Seq[Mustang]) extends Garage {
   type CarType = Mustang
   def copy(cars: Seq[Mustang]) = MustangGarage(cars)
}

val m = Mustang(Benzin(0))
val g0 = MustangGarage(Seq(m))
val g1 = g0.refuel(m, Benzin(45))
于 2012-06-30T15:05:47.497 に答える