Тип коллекции, сгенерированный для for с yield - PullRequest
22 голосов
/ 01 июня 2010

Когда я оцениваю for в Scala, я получаю неизменный IndexedSeq (набор с характеристиками производительности, подобными массиву, такими как эффективный произвольный доступ):

scala> val s = for (i <- 0 to 9) yield math.random + i
s: scala.collection.immutable.IndexedSeq[Double] = Vector(0.6127056766832756, 1.7137598183155291, ...

Всегда ли for с yield возвращает IndexedSeq, или он также может возвращать некоторый другой тип класса коллекции (например, LinearSeq)? Если он также может возвращать что-то еще, то что определяет тип возвращаемого значения и как я могу на него повлиять?

Я использую Scala 2.8.0.RC3.

Ответы [ 2 ]

19 голосов
/ 01 июня 2010

Спасибо michael.kebe за ваш комментарий.

Это объясняет, как for переводится в операции с map, flatMap, filter и foreach. Итак, мой пример:

val s = for (i <- 0 to 9) yield math.random + i

переводится примерно так (я не уверен, что в данном случае это map или flatMap):

val s = (0 to 9) map { math.random + _ }

Тип результата операций, таких как map для коллекций, зависит от коллекции, для которой вы ее вызываете. Тип 0 to 9 является Range.Inclusive:

scala> val d = 0 to 9
d: scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Результатом операции map на этом является IndexedSeq (из-за содержимого компоновщика внутри библиотеки коллекций).

Итак, чтобы ответить на мой вопрос: результат for (...) yield ... зависит от того, какой тип находится внутри парантезов. Если я хочу получить List в результате, я мог бы сделать это:

scala> val s = for (i <- List.range(0, 9)) yield math.random + i
s: List[Double] = List(0.05778968639862214, 1.6758775042995566, ...
6 голосов
/ 30 апреля 2013

Вы всегда можете преобразовать диапазон в список, используя toList:

> val s = for (i <- (0 to 9).toList) yield math.random + i
> s  : List[Double]
...