Reputation: 18034
Refer to below snippet:
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]
What is the easiest way to get this to work? I know I have to define some implicit conversions.
Note: the class Foo
is inside a library so I cannot edit that code. I need to do it outside Foo
.
I could not find answer to this particular case despite there being several examples of using Numeric
types
Upvotes: 2
Views: 75
Reputation: 51693
You can define necessary implicit:
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)
}
}
or just
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 = ???
}
Or you can define your own extension method
implicit class FooList(foos: List[Foo]) {
def sum1: Foo = foos.foldLeft(new Foo(0))(_ + _)
}
l.sum1
Upvotes: 3
Reputation: 18434
The full signature for List
's sum
method is:
def sum[B >: A](implicit num: Numeric[B]): B
So you must provide an implicit Numeric
for your class, or some superclass of your class:
implicit val fooNumeric = new Numeric[Foo] {
def compare(x: Foo, y: Foo): Int = ???
def plus(x: Foo, y: Foo): Foo = ???
... other methods ...
}
My guess is sum
only needs plus
to work correctly, but you'll at least have to give a dummy implementation of the other abstract Numeric
methods to get it to compile.
Upvotes: 2