Il problema è che il implicit def
non è considerato per la conversione argomento, se non si specifica la definizione del metodo di fare così.
Quindi, se si dispone di qualcosa come Real(5).foo
e foo
è definito solo per complesso, il implicit def
funzionerà per quello.
Se si dispone di un metodo come: def foo(c : Complex) = ...
non si può chiamare con foo(Real(5))
invece.
Se si desidera applicare la conversione implicita, è necessario specificare il metodo in modo che i relativi argomenti possano essere convertiti. Per il metodo di cui sopra foo
si potrebbe fare in questo modo:
def foo[T](c : T)(implicit ct : T => Complex) = ...`
allora è valida per chiamare foo(Real(5))
e saranno utilizzati la conversione.
Adattato al vostro problema specifico, si potrebbe scrivere il metodo di test come questo:
def test[G <: GroupUnderAddition[G],T](a : T, b : G)(implicit ag: T => G) = a + b
Specificando, che le conversioni implicite da T
a G
devono essere presi in considerazione, si consente il metodo test
di accettare ora test(Real(5), Complex(2,1))
.
Tuttavia, non funzionerà ancora al contrario. Quindi non puoi ancora chiamarlo con test(Complex(2,1), Real(5))
, perché non c'è alcuna conversione implicita del secondo argomento.
Un modo semplice per tenere conto sia per la conversione sarebbe quella di scrivere in questo modo:
def test[G <: GroupUnderAddition[G],T1, T2](a : T1, b : T2)(implicit ag: T1 => G, bg: T2 => G) = a + b
Purtroppo, il compilatore deriva in qualche modo Any
per G
quando si chiama questo metodo come sopra. Non so in questo momento, come risolvere questo problema e ho postato questa risposta nella speranza che qualcun altro possa riempire questo ultimo pezzo del puzzle.
Data la definizione finale di cui sopra si può almeno chiamare il metodo in entrambi i casi, quando si specificano i tipi di completi:
println(test[Complex,Real,Complex](Real(5), Complex(2, 1)))
println(test[Complex,Complex,Real](Complex(2,1), Real(5)))
Certo che potrei fare questo, ma voglio mantenere i farmaci generici. Facendolo a modo tuo, se volessi chiamare test con due polinomi, dovrei riscrivere il tutto. –
Sì, ma hai 2 diversi problemi, il primo è che vuoi creare il generico 'GroupUnderAddition' che implementerebbe il metodo' + '. D'altra parte si desidera avere uno specifico 'GroupUnderAddition' che implementa 2 diversi tipi di numeri:' Real' e 'Complex'. Quindi hai un altro trucco, è per questo che hai pensato a "implicit def", ma nel tuo caso non ho trovato una soluzione con questo. Il test –