Functional Programming and Meta-Operators
17.1 Higher-Order Functions
my @nums = 1..10;
say @nums.map(* ** 2);
say @nums.grep(*.is-prime);
say @nums.reduce(&infix:<+>); # 55
say @nums.reduce({ $^a * $^b }); # 3628800
say @nums.first(* > 5), ' ', @nums.first(* > 5, :k); # 6 5 (value and index)
say @nums.classify({ $_ %% 2 ?? 'even' !! 'odd' });
say @nums.categorize({ ($_ %% 2 ?? 'even' !! 'odd', $_ > 5 ?? 'big' !! 'small') });
say @nums.produce(&[+]); # running totals: (1 3 6 10 ... 55)
say @nums.toggle(* < 4); # (1 2 3)
my &compose = &uc ∘ &flip; # function composition (also o)
say compose('raku'); # UKAR
(&say ∘ * * 2)(21); # prints 42
my &add3 = -> $a, $b, $c { $a + $b + $c };
my &add-10-20 = &add3.assuming(10, 20);
say add-10-20(5); # 3517.2 Reduction Meta-Operator [op]
say [+] 1..100; # 5050
say [*] 1..10; # 3628800
say [max] 3, 9, 2; # 9
say [~] <a b c>; # abc
say [<] 1, 2, 3; # True (is sorted)
say [\+] 1..5; # triangular reduce: (1 3 6 10 15)
say [Z] (1, 2, 3), (4, 5, 6); # transpose: ((1 4) (2 5) (3 6))
say [||] 0, '', 'found', 'x'; # found17.3 Hyper Operators »op«
Hyper operators may evaluate in parallel/any order. Use them for pure operations.
say (1, 2, 3) »+« (10, 20, 30); # (11 22 33) element-wise
say (1, 2, 3) »*» 2; # (2 4 6): the short side is extended
say -« (1, 2, 3); # (-1 -2 -3) prefix hyper
say (1, 2, 3)».is-prime; # method hyper: (False True True)
say <a b c>».uc; # (A B C)
my @matrix = [1, 2], [3, 4];
say @matrix »*» 10; # [[10 20] [30 40]] (descends into nested structures)
my %prices = apple => 1.5, pear => 2;
say %prices »*» 2; # hyper on hash values
say (1, 2, 3) >>+<< (4, 5, 6); # ASCII version17.4 Cross, Zip, Reverse and Other Meta-Operators
say (1, 2) X (<a b>); # ((1 a) (1 b) (2 a) (2 b))
say (1, 2) X~ <a b>; # (1a 1b 2a 2b)
say (1, 2, 3) X* 10; # (10 20 30)
say <a b c> Z (1, 2, 3); # ((a 1) (b 2) (c 3))
say <a b c> Z=> 1..3; # (a => 1 b => 2 c => 3)
my %h = <a b c> Z=> 1..3; # build a hash
say (1, 2, 3) Z+ (10, 20, 30); # (11 22 33)
say 2 R- 10; # 8 (reversed operands: 10 - 2)
say 5 !== 6; # True (negated ==)
say [R~] <a b c>; # cba
say (1, 2, 3) Z~ <x y z>; # (1x 2y 3z)17.5 Feeds
my @result;
(1..20) ==> grep(*.is-prime) ==> map(* ** 2) ==> @result;
say @result; # [4 9 25 49 121 169 289 361]
@result <== map(* + 1) <== (1, 2, 3);