Это не работает, потому что вы используете ->
, который является (встроенный) оператор:
implicit final class ArrowAssoc[A](self : A) extends scala.AnyVal {
@scala.inline
def ->[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
def →[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
}
Вы можете видеть, что к тому времени, B вычисляется, А уже «фиксированный». Давайте просто скажем, что вы можете только (неявно) преобразовать правую часть кортежа при использовании ->
оператора:
implicit def stringToInt(str: String): Int = 10
implicit def intToStr(str: Int): String = "a"
val a: Map[Int, Int] = Map(10 -> "asd") //fine
val b: Map[Int, Int] = Map("asd" -> 20) // error! cant change left side
val c: Map[String, String] = Map("asd" -> 20) // fine
val d: Map[String, String] = Map(10 -> "asd") // error! cant change left side
Из-за подобные причуды компилятора, связанных с использованием оператора ->
, @ решение Йорга работает в одном направлении, но не другой:
implicit def tupleIntifier(t: (String, Int)) = (10, 10)
implicit def tupleIntifier2(t: (Int, String)) = (10, 10)
val a: Map[Int, Int] = Map("asd" -> 20) // uses tupleIntifier
val b: Map[Int, Int] = Map(10 -> "asd") // fails!!
Однако, если вы не использовать ->
оператора в целом и просто использовать (key, value)
синтаксис, он будет работать:
val a: Map[Int, Int] = Map((10, "asd"))
val b: Map[Int, Int] = Map(("asd", 20))
implicit def stringToInt(str: String): Int = 15
println(a) // prints Map(10 -> 15)
println(b) // prints Map(15 -> 20)
Реальная проблема довольно скучная, вот о написании тестов с помощью скалята. Мне нужно преобразование для удобочитаемости. –