2016-07-10 9 views
2

Я просто посмотрел на объявление метода List::map и был растерян от его осложнений. Вот как это выглядит:Как понять Список :: объявление карты в scala?

final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = { 

Ну, я понимаю, что implicit есть (насколько я получил, класс типа на основе признака CanBuildFrom будет автоматически введен компилятором, если в области видимости). Но что означает здесь That?

Я понимаю map(f: A => B) как функторном вещь, которая отображает каждую функцию f: A => B к функции между соответствующим Монадическими значениями от List(A) и List(B). Поэтому я ожидал, что тип возврата будет List[B].

BTW, это то, что мы на самом деле имеем в случае Option.

def map[B](f: A => B): Option[B] 

Оба List и Option являются монады. Что такое трюк с List?

+0

связанный: [Является ли библиотека коллекций Scala 2.8 примером «самой длинной записки о самоубийстве в истории»?] (Http://stackoverflow.com/questions/1722726/is-the-scala-2-8-collections- library-a-case-of-the-longest-suicide-note-in-hist) – stholzm

+2

'Это' просто параметр типа. Они могли бы выбрать 'C', или' T', или что-то еще. 'That' часто выбирается для имени типа вывода, так что' this' становится 'That'. – jwvh

+0

@stella Эй, просто проверяя, разрешено ли это – slouc

ответ

2

Вы можете прочитать об архитектуре этих коллекций here. Я думаю, что он используется для указания правильного типа возврата операции. Например, при вызове toSet на List, неявное CanBuildFrom[List[A], B, Seq[A]] должен находиться в области видимости ...

3

Отображение коллекции может результат в той же коллекции (только параметризированного с другим типом), но это не делает обязательно будьте так. Это может привести к совершенно другой коллекции. Например,

val myMap = Map("firstName" -> "foo", "lastName" -> "bar") 
val result = myMap map (_._1.length) 

Мы начали с Map[String, String] и в конечном итоге с Iterable[Int]. Вот почему Traversable s (обратите внимание, что Traversable является «абстрактным признаком» и TraversableLike является «чертой реализации») имеют этот неявный строитель, называемый CanBuildFrom. Option не Traversable и не нужен вся эта прецизионная техника - мы знаем, что отображение Option всегда приводит к Option.

При выполнении map на Traversable с, компилятор будет найти соответствующее значение типа CanBuildFrom в объекте компаньон (например, тот, here's для списка). Если он не найден, он будет идти на один уровень выше и т. Д. Проверьте docs (найдите на странице «Свойство CanBuildFrom» и начните оттуда).

Смежные вопросы