Курс Raku / Розширені / Оператори / Метаоператори

Перехресні, гіпер- та заперечні

Окрім згортки та zip, у Raku є ще кілька метаоператорів. Три з них варто знати вже тут.

Перехресний — X

Перехресний метаоператор X парує кожен елемент одного списку з кожним елементом іншого — це декартів добуток:

say <a b> X <1 2>; # ((a 1) (a 2) (b 1) (b 2))

Як і zip, він може огортати оператор, щоб діяти на кожну пару. X~ з’єднує кожну пару в рядок, а X* перемножує:

say <a b> X~ <1 2>;         # (a1 a2 b1 b2)
say (1, 2, 3) X* (10, 100); # (10 100 20 200 30 300)

Якщо zip іде двома списками в ногу, то перехресний оператор поєднує їх усіма можливими способами.

Гіпер — »…«

Гіпероператор застосовує оператор до кожного елемента списку. Оператор загортається у кутові »…« (або ASCII-варіант >>…<<). З двома списками він працює поелементно, як zip; з одним значенням з одного боку він розтягує це значення на весь список:

say (1, 2, 3) »+» (10, 20, 30); # (11 22 33)
say (1, 2, 3) »*» 2;            # (2 4 6)

Дві стрілки не мусять дивитися в один бік, і їхній напрямок вирішує, що станеться, коли списки різної довжини: вістря, спрямоване на список, дозволяє повторювати цей список, щоб зрівнятися з іншим. У ASCII-записі <</>> можливі чотири поєднання:

  • >>op<< — жодна зі сторін не розтягується; списки мають бути однакової довжини, інакше це помилка;
  • >>op>>правий список повторюється, щоб зрівнятися з лівим;
  • <<op<<лівий список повторюється, щоб зрівнятися з правим;
  • <<op>>коротший список повторюється, щоб зрівнятися з довшим.
say (1, 2, 3, 4) <<+>> (10, 20); # (11 22 13 24)  — 10, 20 повторюється як 10, 20, 10, 20

Є й унарна форма, яка викликає метод для кожного елемента. >>.uc переводить кожен рядок у верхній регістр:

say <raku perl>>>.uc; # (RAKU PERL)

Гіпероперації також сигналізують, що роботу можна виконати паралельно — зі спорідненим методом .hyper ви познайомитеся пізніше, у розділі про конкурентне програмування.

Заперечний — !

Постановка ! перед оператором порівняння заперечує його результат. Знайомий != (не дорівнює) — це саме цей метаоператор, застосований до ==, і так само працює для інших булевих операторів, як-от eq та %%:

say 3 != 4;      # True
say 'a' !eq 'b'; # True  — не рівні як рядки
say 5 !%% 2;     # True  — 5 не ділиться на 2

Коротко кажучи, $a !op $b — це просто охайніший спосіб записати !($a op $b).

Так задумано. На відміну від навмисно мінімалістичної мови на кшталт есперанто, яка прагне одного правильного способу висловити кожну річ, Raku радо дає вам кілька, — тож заперечний !eq живе поруч зі спеціальним оператором ne, і обидва означають точно те саме:

say 'a' ne 'b'; # True — та сама перевірка, що й 'a' !eq 'b'

Практика

Виконайте 1 тест за змістом цієї теми.

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

Zip-метаоператори   |   Тест — Гіпер та перехресні


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