Scala:隐式转换适用于 Any 吗?

发布于 2024-09-25 07:38:10 字数 1256 浏览 9 评论 0原文

我想将不同类型层次结构中的一些对象存储到 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] 还不够好。有没有办法让它变得更灵活?

I would like to store some objects from different type hierarchy into List[Any] or similar container, but perform implicit conversions on them later on to do something like type class.
Here is an example:

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

The above code throws an error as follows:

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

If you uncomment AnyPrices, you'd get List(0,0), but that's not what I am expecting.
Do I have to store the manifest into the list for this to work?

Also, List(Prius(2010)) map { implicitPrice(_) } doesn't work either because it wants Price[Prius] and Price[Car] isn't good enough. Is there a way to make it more flexible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红尘作伴 2024-10-02 07:38:10

因此,一旦对象减少到 Any,我就无法获得类型类。我使用 Manifest 的尝试也失败了,因为即使我有 T ,我似乎也无法将 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) }

So, looks like I can't get a type class once the objects are reduced to Any. My attempt of using Manifest also failed, since there seems to be no way for me to cast an Any into T even if I have the Manifest[T] object.

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

gives me

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

so it seems like I have to resolve things into Price before I stick them into 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) }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文