Зачем мне нужен явный тип доказательств / почему эта привязка типа Scala терпит неудачу? - PullRequest
4 голосов
/ 12 декабря 2011

Ниже первый случай успешен, а второй - нет. Зачем мне нужен явный тип доказательств / почему эта привязка типа Scala терпит неудачу? Какое конкретное ограничение выводителя типа здесь при решении для A?

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> view(List(1)) bar
res37: Int = 0

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

scala> view(List(1)) bar
<console>:149: error: inferred type arguments [Nothing,List[Int]] do not conform to method view's type parameter bounds [A,C <: scala.collection.immutable.Seq[A]]
              view(List(1)) bar
              ^

Ответы [ 2 ]

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

Вывод типа, к сожалению, плохо работает с параметрами типа (такими как C), которые ограничены (типы, которые содержат) другими параметрами типа в списке параметров того же типа (здесь, A).

Версия, которая кодирует ограничение с использованием неявного аргумента, не страдает от этого ограничения, поскольку ограничения, налагаемые имплицитами, решаются отдельно от ограничений, налагаемых границами параметров типа.

Вы также можете избежать цикла, разделив тип xs на конструктор типов, который абстрагируется над коллекцией (CC), и (правильный) тип (A), который абстрагируется над его элементами, например:

scala> implicit def view[A, CC[x] <: Seq[x]](xs: CC[A]) = new { def bar = 0 } 
view: [A, CC[x] <: Seq[x]](xs: CC[A])Object{def bar: Int}

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

Подробнее о таких типах, как CC, см. Что такое тип с более высоким родом в Scala?

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

Я действительно не знаю, почему это происходит, хотя я догадываюсь, что это связано с дисперсией параметра типа Seq. Я мог бы заставить следующее работать, хотя:

implicit def view[A, C[~] <: Seq[~] forSome { type ~ }](xs: C[A]) = 
   new { def bar = 0 } 

Есть ли причина, по которой вы хотите C - я имею в виду, планируете ли вы использовать C внутри метода? Потому что, если нет, то почему бы просто

implicit def view[A](xs: Seq[A]) = new { def bar = 0 }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...