Подтвердить что ты не робот

Как неявный <: <помогает найти параметры типа

Несколько вопросов возникают, когда я читаю 7.3.2 Ограничения типа захвата от Джошуа Scala в глубину. Пример, взятый из книги:

scala> def peek[C, A](col: C)(implicit ev: C <:< Traversable[A]) = (col.head, col)
peek: [C, A](col: C)(implicit ev: <:<[C,Traversable[A]])(A, C)

scala> peek(List(1, 2, 3))
res9: (Int, List[Int]) = (1,List(1, 2, 3))

Кажется очевидным, что C оказывается List[Int] по 1-му параметру список. И как <:< применяет ограничение типа по дисперсии, объясняется в книге. Но я не совсем понимаю, как это помогает найти A.

Я понимаю, что из первого списка параметров Scala обнаруживает C: List[Int], то он ищет implicit ev: <:<[List[Int], Traversable[A]]. На данный момент A остается неизвестным. Он "тянет" два имплицита conforms[List[Int]] и conforms[Traversable[A]] в соответствие ev. В любом случае для удовлетворения дисперсии должно выполняться List[Int] <: Traversable[A], что приводит к выводу, что A Int.

Работает ли он так, как я описываю здесь? Особенно в том, как/когда A выводится.

4b9b3361

Ответ 1

Как прокомментировал педрофурла, у вас все получилось - с небольшой квалификацией. Вы говорите, что компилятор "тянет" conforms[Traversable[A]], но здесь нет необходимости в каком-либо таком экземпляре. Чтобы упростить пример, где он очень четко показывает, какие импликации находятся в области видимости:

trait Foo[-From, +To]

implicit object intListFoo extends Foo[List[Int], List[Int]]

Теперь определенно нет Foo[Traversable[Int], Traversable[Int]], но мы можем написать следующее:

scala> implicitly[Foo[List[Int], Traversable[Int]]]
res0: Foo[List[Int],Traversable[Int]] = [email protected]

Более или менее точно то же самое происходит в вашем примере. В этом случае мы бы имели экземпляр Traversable[Int] <:< Traversable[Int] вокруг, если бы нам это было нужно, но мы не для этого конкретного неявного поиска.