如何使用sum来定制类型列表?

时间:2017-11-15 18:07:10

标签: scala

请参阅以下代码段:

class Foo(val b:BigDecimal) {
  def +(f:Foo) = new Foo(b+f.b) 
}
val l = List(new Foo(1), new Foo(2))

l.sum // gives error: could not find implicit value for parameter num: Numeric[Foo]

最简单的方法是什么?我知道我必须定义一些隐式转换。

注意:类Foo位于库中,因此我无法编辑该代码。我需要在Foo之外进行。

尽管有几个使用Numeric类型

的例子,但我找不到这个特定案例的答案

2 个答案:

答案 0 :(得分:3)

您可以定义必要的隐含:

  class Foo(val b:BigDecimal) {
    def +(f:Foo) = new Foo(b+f.b)
  }
  object Foo {
    implicit val numericFoo: Numeric[Foo] = new Numeric[Foo] {
      override def plus(x: Foo, y: Foo): Foo = new Foo(x.b + y.b)
      override def minus(x: Foo, y: Foo): Foo = new Foo(x.b - y.b)
      override def times(x: Foo, y: Foo): Foo = new Foo(x.b * y.b)
      override def negate(x: Foo): Foo = new Foo(-x.b)
      override def fromInt(x: Int): Foo = new Foo(x)
      override def toInt(x: Foo): Int = x.b.toInt
      override def toLong(x: Foo): Long = x.b.toLong
      override def toFloat(x: Foo): Float = x.b.toFloat
      override def toDouble(x: Foo): Double = x.b.toDouble
      override def compare(x: Foo, y: Foo): Int = x.b.compare(y.b)
    }
  }

或只是

implicit val numericFoo: Numeric[Foo] = new Numeric[Foo] {
  override def plus(x: Foo, y: Foo): Foo = x + y
  override def minus(x: Foo, y: Foo): Foo = ???
  override def times(x: Foo, y: Foo): Foo = ???
  override def negate(x: Foo): Foo = ???
  override def fromInt(x: Int): Foo = new Foo(x)
  override def toInt(x: Foo): Int = ???
  override def toLong(x: Foo): Long = ???
  override def toFloat(x: Foo): Float = ???
  override def toDouble(x: Foo): Double = ???
  override def compare(x: Foo, y: Foo): Int = ???
}

或者您可以定义自己的扩展方法

  implicit class FooList(foos: List[Foo]) {
    def sum1: Foo = foos.foldLeft(new Foo(0))(_ + _)
  }

  l.sum1

答案 1 :(得分:2)

List的{​​{1}}方法的完整签名是:

sum

因此,您必须为您的班级或班级的某些超类提供隐式def sum[B >: A](implicit num: Numeric[B]): B

Numeric

我的猜测implicit val fooNumeric = new Numeric[Foo] { def compare(x: Foo, y: Foo): Int = ??? def plus(x: Foo, y: Foo): Foo = ??? ... other methods ... } 只需要sum才能正常工作,但您至少必须提供其他抽象plus方法的虚拟实现才能使其编译。