Неявное преобразование метода в A => C
проблематично, поскольку компилятор не может легко перечислить все возможные классы C
, которые имеют ожидаемый метод +
, а затем перейти к поиску все возможные методы, которые принимают B
и дают C
- этот поиск будет длиться вечно.
Я бы предложил избежать неявных аргументов типа B => C
для неизвестного типа C
. Если вам нужен конвертер, то дайте ему какое-то конкретное имя, например,
trait Unwrap[A, B] extends (A => B)
, который вы затем используете только в этом неявном цепочке.
Грубый набросок того, что вы можете попробовать вместо этого:
import scala.language.implicitConversions
trait ParameterizedBy[A, B] {
val parameterized: B
}
object ParameterizedBy {
implicit def toParameterized[A, B, C](p: ParameterizedBy[A, B])(
implicit f: Unwrap[B, C]): C = f(p.parameterized)
}
trait Wraps[A] {
val wrapped: A
}
object Wraps {
implicit def toWrapped[A](w: Wraps[A]): A = w.wrapped
}
trait Unwrap[A, B] extends (A => B)
object Unwrap {
implicit def unwrap[A]: Unwrap[Wraps[A], A] = new Unwrap[Wraps[A], A] {
def apply(w: Wraps[A]): A = w.wrapped
}
}
val p = new ParameterizedBy[String, Wraps[Int]] {
override val parameterized: Wraps[Int] = new Wraps[Int] {
override val wrapped = 6
}
}
p - 5 // works
(p: Int) + 5 // works with type ascription (to avoid conflicts with `+ String`)