Как воспользоваться mkNumericOps в Scala? - PullRequest
0 голосов
/ 13 января 2020

Я пытаюсь определить новый тип, который может вести себя по существу как число (для конкретности, скажем, Double). Я хотел бы перегрузить операторы этого типа, и я мог бы сделать это явно, но чтобы избежать повторения, я хотел бы воспользоваться преимуществами методов в NumericOps, которые определены в терминах абстрактных методов в Numeric. Насколько я понимаю, я должен иметь возможность просто переопределить методы в Numeric и получить другие бесплатно.

Вот самая простая попытка, которую я могу придумать:

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

Однако это дает мне ошибку несоответствия типов.

Мое понимание последствий все еще довольно шатко, но я бы подумал, что implicit def mkNumericOps(lhs: Container): NumericOps, унаследованный Container, спасет день, неявно преобразовав два объекта Container, являющихся добавил к NumericOps объектам, а затем добавил их, используя метод +, определенный в терминах Container.plus.

Что я здесь не так делаю и как я могу это исправить?

Ответы [ 2 ]

2 голосов
/ 13 января 2020

Вот пример для дополнения комментария класса типов Луиса

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)

, который выводит

res0: Container = Container(2.0)

Импорт обеспечивает infixNumericOps, который компилятор использует для автоматического переписать на

infixNumericOps(Container(1)) + Container(1)
1 голос
/ 13 января 2020

Вам необходимо импортировать mkNumericOps из экземпляра Container:

val container = new Container(1)
import container.mkNumericOps
println(container + container) 

Вы можете отказаться от импорта, определив свой собственный метод + через mkNumericOps, например:

def +(y: Container): Container = mkNumericOps(this) + y
...