How to take advantage of mkNumericOps in Scala?

不打扰是莪最后的温柔 提交于 2021-01-29 09:51:50

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!