Si el compilador busca un implicit (Double, Double) => Double
en ámbito implícito, o bien hay exactamente uno con mayor prioridad y lo elegirá las dos veces, o no (no hay ninguno en alcance implícito, o más de uno con la prioridad más alta) y habrá un error por falta de un valor implícito.
Si desea distinguir, puede tener dos tipos diferentes, ambos extendiendo Function2 [Double, Double, Double]. Por ejemplo
trait Addition extends Function[Double, Double, Double]
trait Multiplication extends Function[Double, Double, Double]
class Example(implicit addition: Addition, implicit multiplication: Multiplication)
Esto puede estar bien, tiene sentido elegir ambas operaciones de forma independiente. Si las dos opciones necesitan ser conistent, podría tener más sentido tener sólo un rasgo tanto con la operación
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)
Por último, todo esto es útil sólo si obtiene las operaciones apropiadas en su alcance implícito "de forma natural". Si usted tiene que hacer que sean implícita cada vez que se crea un ejemplo, al igual que en
implicit val addition = ...
implicit val multiplication =
new Example
que podría así ser explícita.
Además, si se espera que la mayoría de las llamadas a trabajar con el mismo valor, y lo que desea es cambiar algunos de ellos, es posible que en lugar ir para argumentos con valores por defecto
class Example(doSomething1 : (Double, Double) => Double = <default value>, doSomething2 ...)
Usted puede incluso tener ambos, un argumento implícito con el valor predeterminado. Si lo hace, el valor predeterminado se utiliza cuando no se encuentra implícito.