Если компилятор ищет implicit (Double, Double) => Double
в неявной области видимости, либо он точно имеет более высокий приоритет, и он выберет его один раз, либо его нет (либо в неявной области его вообще нет, либо больше чем один с наивысшим приоритетом), и будет ошибка из-за отсутствия неявного значения.
Если вы хотите различать, у вас может быть два разных типа, оба расширяющие Function2 [Double, Double, Double]. Например
trait Addition extends Function[Double, Double, Double]
trait Multiplication extends Function[Double, Double, Double]
class Example(implicit addition: Addition, implicit multiplication: Multiplication)
Это может быть хорошо, имеет смысл выбрать обе операции независимо. Если оба варианта должны быть согласованы, может иметь смысл иметь только одну черту с обоими операциями
trait Ring {
def add(x: Double, y: Double): Double
def mult(x: Double, y: Double): Double
}
// or `case class Ring(
// addition: (Double, Double) => Double,
// multiplication: (Double, Double) => Double)
class Example(implicit ring: Ring)
Наконец, все это полезно, только если вы получаете естественные операции в неявном объеме. Если вам нужно делать их неявными каждый раз, когда вы создаете пример, как в
implicit val addition = ...
implicit val multiplication =
new Example
Вы могли бы также быть явным.
Кроме того, если ожидается, что большинство вызовов будут работать с одним и тем же значением, и вы просто хотите изменить несколько из них, вы можете использовать аргументы со значениями по умолчанию
class Example(doSomething1 : (Double, Double) => Double = <default value>, doSomething2 ...)
Вы можете даже иметь оба этих значения, неявный аргумент со значением по умолчанию. Если вы сделаете это, значение по умолчанию используется, когда неявное не найдено.