raku hyperoperators
03.11.2023 2 min readI first came across hyperoperators in Arne Sommer’s blog post detailing a Raku challenge, where the challenge was to see if a given array was “acronymous”. “Acronymous” is True
when our inputs are ["coke", "sprite"]
and "cs"
(we take the first letters of the array, join them and compare them with the given string).
Here was my original solution:
my $str = @str.map({$_.comb.head}).join("").lc;
Here is Arne Sommer’s solution:
@str>>.substr(0,1).join.lc;
What in the >>
was this? So I did some reading. From the docs (abridged):
Hyper operators… Apply a given operator… to one or two lists
What exactly does this mean? Well, lets look at some examples.
my @foods = <sushi pizza>;
my @nice-foods = @foods >>~>> " is delicious";
say @nice-foods; # [sushi is delicious pizza is delicious]
So, we use the hyperoperator with the operator ~
(used for concatenation), and concatenate ” is delicious” to every item in the list. We could do it with a map
, like so:
my @nice-foods = @foods.map: {$_ ~ " is delicious"}
my @nice-foods = @foods.map({$_ ~ " is delicious"});
But hyperoperators are more exotic. And exotic ==
fun.
What else can we do with hyperoperators? We can call methods on every item in a positional type:
@nice-foods>>.say; # sushi is delicious\npizza is delicious
sub add100 {$^n + 100}
my @nums = 1, 2, 3, 4, 5;
say @nums>>.&add100;
And we can get really crazy and chain hyperoperators with hyper method operators:
my @foods = <sushi pizza>;
(@foods >>~>> " is delicious")>>.say; # sushi is delicious\npizza is delicious
Overall… pretty cool.