问题
I'm trying to define a new type that can behave essentially like a number (for concreteness, let's say a Double
). I'd like to overload operators on this type and I could do this explicitly, but to avoid repetition, I would like to advantage of the methods in NumericOps, which are defined in terms of the abstract methods in Numeric. My understanding is I should be able to just override the methods in Numeric
and get the others for free.
Here's the simplest attempt I can think of:
class Container(val value: Double) extends Numeric[Container] {
override def plus(x: Container, y: Container): Container =
new Container(x.value + y.value)
// override minus, times, etc.
override def toString: String = value.toString
}
println(new Container(1) + new Container(1))
However, this gives me a type mismatch error.
My understanding of implicits is still quite shaky, but I would have thought the implicit def mkNumericOps(lhs: Container): NumericOps
inherited by Container
would save the day by implicitly converting the two Container
objects being added to NumericOps
objects and then adding them using the +
method defined in terms of Container.plus
.
What am I getting wrong here and how can I fix this?
回答1:
Here is an example to supplement Luis' typeclass comment
final case class Container(value: Double)
object Container {
implicit val containerNumeric: Numeric[Container] = new Numeric[Container] {
override def plus(x: Container, y: Container) = Container(x.value + y.value)
override def minus...
}
}
import Numeric.Implicits._
Container(1) + Container(1)
which outputs
res0: Container = Container(2.0)
The import provides infixNumericOps which compiler uses to automatically rewrite to
infixNumericOps(Container(1)) + Container(1)
回答2:
You need to import mkNumericOps
from an instance of Container
:
val container = new Container(1)
import container.mkNumericOps
println(container + container)
You can omit importing by defining your own +
method via mkNumericOps
like so:
def +(y: Container): Container = mkNumericOps(this) + y
来源:https://stackoverflow.com/questions/59711985/how-to-take-advantage-of-mknumericops-in-scala