К сожалению, не имеет значения, что Range
расширяет Iterable[Int]
, это действительно проблема с арностью типов params.Он тоже глубокий, даже основная библиотека страдает от этого местами (просто посмотрите на комментарии в Manifest
)
Вы также столкнетесь с этим, если захотите использовать Карты, Строки и т. Д., Как будто онибыли Iterable
.
Единственное решение, которое я нашел, - это определить несколько неявных преобразований в тип сутенера.
ОБНОВЛЕНИЕ
Проблемаздесь подразумевается вывод параметра типа P
из предоставленного аргумента, который, по-видимому, не имеет параметра типа.По сути, вы пытаетесь сделать для конструктора типов то, что извлекатели будут делать для обычного конструктора, и полиморфизм мешает.
Ваш отредактированный пример работает, потому что этот конкретный вывод не нужен, подвохзаключается в том, что теперь вы можете вернуть только Iterable
и, таким образом, потерять большую часть выгоды CanBuildFrom
Если это не проблема, тогда это более простое решение, так что катайтесь с ним.
В противном случае вам потребуются разные значения для каждого возможного числа типов, которые вы хотите отобразить.
ОБНОВЛЕНИЕ 2
Рассмотрите, как компилятор может обрабатывать ваши различныевыражения при попытке определить, является ли Range
допустимым аргументом:
Take 1:
implicit def iter2foo[P, S[X] <: Iterable[X]](s : S[P]) = new Foo[P,S](s)
S
- тип с более высоким родом, типа * => *
Range
- простой тип, типа *
- Виды не совпадают, поэтому они недействительны
Take 2:
implicit def iter2foo[P, S <: Iterable[P]](s : S) = new Foo[P,Iterable](s)
- Та же проблема,
S
все еще имеет вид * => *
аргумент делаетне соответствует
Взять 3:
implicit def iter2foo[P](s : Iterable[P]) = new Foo[P,Iterable](s)
- Имея предоставленный параметр,
Iterable[P]
- простой тип *
Range
проходит это первое препятствие - Вторая проверка состоит в том, что
Range
является подклассом Iterable[P]
для некоторых P
- Это с
P
, выведенным какInt
- Компилятор рад, что все выводы, проверки границ и т. Д. Успешно завершены