Как работает "1 * BigInt (1) и как я могу сделать то же самое?

Я пытаюсь реализовать некоторый тип номера, и я попал в проблему, которая

mynum * 1

работает, но не

1 * mynum

Я попытался определить неявное преобразование, подобное этому

case class Num(v: Int) {
  def * (o: Int) = new Num(v*o)
}

implicit def int2Num(v: Int) = Num(v)

но это не похоже на работу, потому что я всегда получаю следующую ошибку:

scala> 1 * new Num(2)
<console>:14: error: overloaded method value * with alternatives:
  (x: Double)Double <and>
  (x: Float)Float <and>
  (x: Long)Long <and>
  (x: Int)Int <and>
  (x: Char)Int <and>
  (x: Short)Int <and>
  (x: Byte)Int
 cannot be applied to (Num)
              1 * new Num(2)
                ^

С другой стороны,

1 * BigInt(1)

работает, поэтому должен быть способ, хотя я не мог идентифицировать решение при просмотре кода.

Какой механизм заставить его работать?

EDIT: Я создал новый вопрос с фактической проблемой, которую я ударил, Почему неявное преобразование, не рассматриваемое в этом случае с помощью общих параметров?.

Ответ 1

Я думаю, что вам не хватает * метода в вашем классе Num, который принимает аргумент Num в качестве аргумента.

Ответ 2

Когда приложение a.meth(args) выходит из строя, компилятор ищет неявное представление из a тому, что имеет метод meth. Будет выполняться любое неявное значение или метод, который соответствует A => { def meth(...) }. Если он найден, код переписывается как view(a).meth(args).

Где это выглядит? Сначала он просматривается в текущей области, состоящей из локально определенных имплицитов и импортированных имплицитов.

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

Если это не удается, оно выглядит в неявной области. Это состоит из сопутствующих объектов "частей" типа, который мы ищем. В этом случае мы после A => { def meth(...) }, поэтому просто посмотрим на сопутствующий объект a (и его супер типы).

В Scala trunk неявная область расширила крошечный бит, чтобы включить объекты-компаньоны типов аргументов. Не уверен, что это было уже в 2.9.1, возможно, дружелюбный читатель это выяснит для меня и обновит этот ответ.

Итак, 1 + BigInt(2) расширяется до BigInt.int2bigInt(1) + BigInt(2)