Курс Raku / Функційне, конкурентне, реактивне та веб-програмування / Функційне програмування / Генератори

Лінивий gather

Блок gather є лінивим: він не виконується весь одразу. Він виробляє значення лише тоді, коли їх витягають, а це означає, що gather може описувати нескінченний ряд і все одно бути корисним — ви просто перестаєте брати значення, коли їх достатньо.

Заковика в тому, що результат треба тримати лінивим. Збереження його у звичайному масиві @array спробувало б зібрати всі значення одразу, а для нескінченного ряду це ніколи не завершиться. Натомість тримайте послідовність у скалярі (де вона залишається лінивим Seq) і витягайте з неї зріз:

my $naturals = gather {
    my $n = 1;
    loop {
        take $n++;
    }
}

say $naturals[^5]; # (1 2 3 4 5)

loop не завершується ніколи, але виробляється лише п’ять значень, бо саме стільки ми попросили через [^5]. Витягати з початку можна також за допомогою .head:

say (gather { my $n = 1; loop { take $n++ } }).head(3); # (1 2 3)

Саме лінивість дозволяє gather безпечно моделювати нескінченні потоки: ніщо не обчислюється, поки не знадобиться, і ви берете рівно стільки, скільки хочете.

Навігація курсом

Тест — gather і take   |   Зберіть куби


💪 Або перейдіть одразу до вправ цього розділу.