Это не работает, потому что вы используете ->, который является (встроенным) оператором:
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 оценивается, A уже «исправлено». Скажем так, вы можете (неявно) преобразовать правую часть кортежа только при использовании оператора ->:
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
Из-за подобных причуд компилятора, связанных с использованием оператора ->, решение @Jorg работает в одном направлении, но не в другом:
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)
person
slouc
schedule
11.11.2016