Курс Raku / Функційне, конкурентне, реактивне та веб-програмування / Функційне програмування / Згортка
Процедура reduce
Коли ви хочете згорнути список власною операцією, а не одним
іменованим оператором, скористайтеся процедурою reduce.
Вона приймає блок від двох аргументів і застосовує його вздовж списку,
несучи поточний результат далі:
say (1..5).reduce(* + *); # 15Блок * + * має дві зірочки Whatever: перша — це результат,
накопичений досі, друга — наступний елемент. Тож reduce
обчислює ((((1 + 2) + 3) + 4) + 5), тобто 15 —
те саме, що й [+], але записане блоком.
Щоб побачити ці два аргументи в дії, дайте їм імена й надрукуйте
кожен крок. Гострий блок повертає свій останній вираз, тож
$x + $y є водночас і тим, про що блок друкує, і значенням,
яке він повертає в reduce:
say (1..5).reduce(
-> $x, $y {
say "$x + $y";
$x + $y;
}
);Це друкує:
1 + 2
3 + 3
6 + 4
10 + 5
15Кожен із перших чотирьох рядків є одним викликом блоку.
$x — це результат, накопичений досі, а $y —
наступний елемент списку. Найперший виклик отримує два перші значення
списку, 1 та 2; кожен наступний отримує назад
підсумок попереднього кроку як $x — 3, потім
6, потім 10 — у парі з наступним числом як
$y. Значення блоку стає $x наступного виклику,
а підсумковий результат, 15, — це те, що
reduce повертає, а say друкує в останньому
рядку.
Оскільки блок може бути яким завгодно, reduce є
загальнішим. Наприклад, можна будувати значення крок за кроком:
say (1..4).reduce(-> $acc, $x { $acc * 10 + $x }); # 1234Кожен крок множить акумулятор на десять і додає наступну цифру,
перетворюючи окремі цифри 1, 2, 3, 4 на число
1234.
Як і інші методи, що приймають блок, reduce добре
читається у формі виклику з
двокрапкою, яка прибирає дужки навколо блоку:
say (1..5).reduce: * + *; # 15Коротко: [op] — швидка форма для іменованого оператора,
а reduce — гнучка форма для довільного поєднувального
блоку. Обидві згортають список до одного значення.
Практика
Виконайте 1 тест за змістом цієї теми.
Навігація курсом
← Тест — Метаоператор згортки | Тест — Згортка →
💪 Або перейдіть одразу до вправ цього розділу.