Изменить: поскольку я написал вопрос с неправильным примером и не описал свои проблемы, я сделаю это снова!
Мне кажется, что #flat_map, хотя и является частью класса Enumerator::Lazy, сам по себе не очень поддающийся перечислению.
Этот пример правильно работает:
(1..Float::INFINITY).flat_map { |s| [s,s] }.take(4).to_a
Ленивая реализация также будет работать:
(1..Float::INFINITY).flat_map { |s| [s,s] }.take(4).to_a
Это будет учитывать только то, что массив, сгенерированный в блоке, конечен. Но они также будут полностью оценены перед вызовом take(4). Что не очень лениво.
Следовательно, это не удастся:
(1..Float::INFINITY).lazy.flat_map { |i| (i..Float::INFINITY).map(&:to_i) }.take(4).force
Потому что «бесконечный диапазон для массива» будет полностью оценен до того, как произойдет ленивый вызов. Я бы ожидал, что он будет «ленивым по умолчанию». Я имею в виду, я понимаю, в чем заключается загадка, но я ожидаю, что это произойдет следующим образом: flat_map оценивает каждый экземпляр лениво, знает, что результатом будет массив (или, по крайней мере, перечисляемый), и применяет ленивый механизм в теме. следовательно, (i..Float::INFINITY).map(&:to_i) будет лазифицирован (что не очень совместимо, поскольку вызов map(&:to_i) "заставит" его вычислить).
flat_map
пингуетRange
, а неEnumerator::Lazy
. Здесь просто нет лени, и вы не ожидаете, что она будет. - person Jörg W Mittag   schedule 10.12.2014