Scala: Неявные преобразования работают на Any? - PullRequest
1 голос
/ 30 сентября 2010

Я хотел бы сохранить некоторые объекты из другой иерархии типов в List[Any] или аналогичном контейнере, но позже выполнить неявные преобразования для них, чтобы сделать что-то вроде класса типов. Вот пример:

abstract class Price[A] {
  def price(a: A): Int
}

trait Car
case class Prius(year: Int) extends Car
trait Food
case class FriedChicken() extends Food

object Def {
  // implicit object AnyPrices extends Price[Any] {
  //   def price(any: Any) = 0
  // }

  // implicit object PriusPrices extends Price[Prius] {
  //   def price(car: Prius) = 100
  // }

  implicit object CarPrices extends Price[Car] {
    def price(car: Car) = 100
  }

  implicit object FoodPrices extends Price[Food] {
    def price(food: Food) = 5
  }
}

def implicitPrice[A: Price](x: A) = implicitly[Price[A]].price(x)

import Def._  
val stuff: List[Any] = List(Prius(2010), FriedChicken())
stuff map { implicitPrice(_) }

Приведенный выше код выдает ошибку следующим образом:

error: could not find implicit value for evidence parameter of type Price[Any]
       stuff map { implicitPrice(_) }
                                ^

Если раскомментировать AnyPrices, вы получите List(0,0), но это не то, чего я ожидаю. Нужно ли сохранять манифест в списке, чтобы это работало?

Кроме того, List(Prius(2010)) map { implicitPrice(_) } тоже не работает, потому что хочет Price[Prius], а Price[Car] недостаточно. Есть ли способ сделать его более гибким?

1 Ответ

0 голосов
/ 30 сентября 2010

Итак, похоже, я не могу получить класс типов, когда объекты уменьшены до Any. Моя попытка использовать Manifest также потерпела неудачу, так как у меня, похоже, нет никакого способа бросить Any в T, даже если у меня есть объект Manifest[T].

import reflect.Manifest._
def add [A, B >: A](stuff: A, list: List[(B, Manifest[_])])(implicit m: Manifest[A]) = (stuff, m) :: list
val stuff2 = add(Prius(2000), add(FriedChicken(), Nil))
stuff2 map { x =>
  val casted = x._2.erasure.cast(x._1)
  implicitPrice(casted)
}

дает мне

error: could not find implicit value for evidence parameter of type Price[Any]

так что, похоже, мне нужно разрешить вещи в Price, прежде чем я вставлю их в List:

abstract class Price[A] {
  def price(a: Any): Int
}

trait Car
case class Prius(year: Int) extends Car
trait Food
case class FriedChicken() extends Food

object Def {  
  implicit object PriusPrices extends Price[Prius] {
    def price(car: Any) = 100
  }

  implicit object FriedChickenPrices extends Price[FriedChicken] {
    def price(food: Any) = 5
  }
}

import Def._  

def add [A, B >: A](stuff: A, list: List[(B, Price[_])])(implicit p: Price[A]) = (stuff, p) :: list
val stuff = add(Prius(2000), add(FriedChicken(), Nil))
stuff map { x => x._2.price(x._1) }
...