Если вы посмотрите на определение map
или filter
для List
, каждая функция должна выполнить итерацию всего списка. В частности, для map
он вернет новый List
, полученный в результате применения данной функции f к каждому элементу этого списка и сбора результатов.
Затем map
вернет новый список с тем жезначения в качестве исходного списка с побочным эффектом печати «Some req / res» один раз для каждого элемента.
res0: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
scala>.map{x => println("Some req/res"); x}
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
Some req/res
res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
Затем filter
создаст новый список, в который будут возвращены только элементы, соответствующие предикату.
scala> .filter{_ % 2 == 0}
res2: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
Наконец, take(3)
создаст новый списокне более 3 элементов.
scala> .take (3)
res3: List[Int] = List(2, 4, 6)
Если вы хотите отложить эффекты map
и filter
, вам нужен другой тип данных. Вы можете использовать Stream
в этом случае, но используйте окончательный toList
, чтобы собрать результаты в список.
scala> List(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20).toStream
res8: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> .map{x => println("Some req/res"); x}
Some req/res
res9: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> .filter{_ % 2 == 0}
Some req/res
res10: scala.collection.immutable.Stream[Int] = Stream(2, ?)
scala> .take(3)
res11: scala.collection.immutable.Stream[Int] = Stream(2, ?)
scala> .toList
Some req/res
Some req/res
Some req/res
Some req/res
res13: List[Int] = List(2, 4, 6)