Here is exercise 5.F.2 from Charles C. Pinter's Book of Abstract Algebra:
Let G be the group {e, a, b, b^2, b^3, ab, ab^2, ab^3} generators satisfy a^2 = e , b^4 = e , ba = ab^3 . Write table G ( G is called the dihedral group of D4.)
Here is a small Perl 6 program that introduces the solution:
sub generate(%eqs, $s) { my @results = (); for %eqs.kv -> $key, $val { if $s ~~ /$key/ { @results.push($s.subst(/$key/, $val)); } if $s ~~ /$val/ { @results.push($s.subst(/$val/, $key)); } } for @results -> $result { take $result; } my @arrs = @results.map({ gather generate(%eqs, $_) }); my $i = 0; while (1) { for @arrs -> @arr { take @arr[$i]; } $i++; } } sub table(@G, %eqs) { printf " |"; for @G -> $y { printf "%-5s|", $y; }; say ''; printf "-----|"; for @G -> $y { printf "-----|"; }; say ''; for @G -> $x { printf "%-5s|", $x; for @G -> $y { my $result = (gather generate(%eqs, "$x$y")).first(* (elem) @G); printf "%-5s|", $result; } say '' } }
Here's what the resulting table looks like:

Focus on these specific lines from generate :
my @arrs = @results.map({ gather generate(%eqs, $_) }); my $i = 0; while (1) { for @arrs -> @arr { take @arr[$i]; } $i++; }
A recursive call to generate is performed for each of the elements in @results . Then we efficiently execute manual "zip" in the resulting sequences. However, Perl 6 has zip and the Z operator.
Instead of the above lines, I would like to do something like this:
for ([Z] @results.map({ gather generate(%eqs, $_) })).flat -> $elt { take $elt; }
So here is the full generate using Z :
sub generate(%eqs, $s) { my @results = (); for %eqs.kv -> $key, $val { if $s ~~ /$key/ { @results.push($s.subst(/$key/, $val)); } if $s ~~ /$val/ { @results.push($s.subst(/$val/, $key)); } } for @results -> $result { take $result; } for ([Z] @results.map({ gather generate(%eqs, $_) })).flat -> $elt { take $elt; } }
The problem with the generation version of Z is that it freezes ...

So my question is, is there a way to write generate in terms of Z ?
Besides this basic question, feel free to share alternative solutions that explore and demonstrate Perl 6.
As another example, here run 5.F.3 from the same book:
Let G be the group {e, a, b, b^2, b^3, ab, ab^2, ab^3} , the generators satisfy a^4 = e , a^2 = b^2 , ba = ab^3 . Write a table G (G is called a group of quaternions.)
And the above program displays a table:

Aside, this program has been converted from version to C #. Here's how generate looks there using LINQ and the ZipMany version, courtesy of Eric Lippert .
static IEnumerable<string> generate(Dictionary<string,string> eqs, string s) { var results = new List<string>(); foreach (var elt in eqs) { if (new Regex(elt.Key).IsMatch(s)) results.Add(new Regex(elt.Key).Replace(s, elt.Value, 1)); if (new Regex(elt.Value).IsMatch(s)) results.Add(new Regex(elt.Value).Replace(s, elt.Key, 1)); } foreach (var result in results) yield return result; foreach (var elt in ZipMany(results.Select(elt => generate(eqs, elt)), elts => elts).SelectMany(elts => elts)) yield return elt; }
The whole C # program: link .