Следуя другому вопросу, я спросил, Scala 2.8 breakout, я хотел немного подробнее узнать о методе Scala TraversableLike[A].map
, подпись которого следующим образом:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
Обратите внимание на несколько вещей об этом методе:
- Требуется функция, поворачивающая каждый
A
в проходящем черезB
. - Он возвращает
That
и принимает неявный аргумент типаCanBuildFrom[Repr, B, That]
.
Я могу назвать это следующим образом:
> val s: Set[Int] = List("Paris", "London").map(_.length)
s: Set[Int] Set(5,6)
Что Я не могу понять, как тот факт, что That
привязан к B
(то есть, это некоторая коллекция B), принудительно выполняется компилятором. Параметры типа выглядят независимыми как от сигнатуры выше, так и от сигнатуры самого признака CanBuildFrom
:
trait CanBuildFrom[-From, -Elem, +To]
Как компилятор Scala гарантирует, что That
не может быть принужден к чему-то, что не имеет смысла?
> val s: Set[String] = List("Paris", "London").map(_.length) //will not compile
Как компилятор решает, какие неявные объекты CanBuildFrom
находятся в области для вызова?