Почему происходит неявное преобразование Scala, когда работает явное преобразование? - PullRequest
4 голосов
/ 12 декабря 2011

Почему не работает следующее неявное преобразование, даже если работает явный вызов функции?

scala> implicit def view[A, C](xs: C)(implicit ev: C <:< Iterable[A]) = new { def bar = 0 } 
view: [A, C](xs: C)(implicit ev: <:<[C,scala.collection.immutable.Iterable[A]])java.lang.Object{def bar: Int}

scala> List(1) bar
<console>:147: error: Cannot prove that List[Int] <:< scala.collection.immutable.Iterable[A].
              List(1) bar
                  ^

scala> view(List(1)) bar
res37: Int = 0

Ответы [ 2 ]

0 голосов
/ 12 января 2012

Проще говоря, как следует из сообщения об ошибке, он не может вывести A.Нет никакой информации, которую компилятор может использовать, чтобы определить, что A должно быть, поэтому он должен предполагать, что это может быть что угодно.

Вы могли бы возразить, что он может вывести A из C <:< Iterable[A], но это может привести кпроблема с ног на голову: вместо использования <:< для проверки ограничений он будет использовать ограничения для вывода типа A!Эта логика не правильная.

0 голосов
/ 12 декабря 2011

Я на самом деле не отвечаю на ваш вопрос (то есть я отвечаю на «как мне сделать эту работу», а не на «почему это не работает»);в любом случае, надеюсь, это поможет кому-то еще добиться некоторого прогресса в направлении ответа.

Итак ... В первом случае компилятор не может правильно сделать вывод, что A является Int, учитывая, что C является List [Int].Честно говоря, я более удивлен тем, что передача списка явно работает, так как отношения между A и C настолько непрямы (у вас есть A и C, поскольку C является подтипом Iterable [A], а C является List [Int], тогда A должен быть Int, а не очень простым выводом ...).

Вы можете заставить его работать, если будете более четко понимать отношения между C и A, например:

scala> implicit def view[A, C[A]](xs: C[A])(implicit ev: C[A] <:< Iterable[A]) = 
       new { def bar = 0 }
view: [A, C[A]](xs: C[A])(implicit ev: <:<[C[A],Iterable[A]])java.lang.Object{def bar: Int}

scala> List(1) bar
res0: Int = 0

или (учитывая, что вы не используете A):

scala> implicit def view[C](xs: C)(implicit ev: C <:< Iterable[_]) = 
       new { def bar = 0 }

scala> List(1) bar
res1: Int = 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...