In List§
See primary documentation in context for routine produce
multi produce(&with, *@values) multi method produce(List:D: &with)
Generates a list of all intermediate "combined" values along with the final result by iteratively applying a function which knows how to combine two values.
If @values
contains just a single element, a list containing that element is returned immediately. If it contains no elements, an exception is thrown, unless &with
is an operator with a known identity value.
If &with
is the function object of an operator, its inherent identity value and associativity is respected - in other words, (VAL1, VAL2, VAL3).produce(&[OP])
is the same as VAL1 OP VAL2 OP VAL3
even for operators which aren't left-associative:
# Raise 2 to the 81st power, because 3 to the 4th power is 81 [2,3,4].produce(&[**]).say; # OUTPUT: «(4 81 2417851639229258349412352)» say produce &[**], (2,3,4); # OUTPUT: «(4 81 2417851639229258349412352)» say [\**] (2,3,4); # OUTPUT: «(4 81 2417851639229258349412352)» # Subtract 4 from -1, because 2 minus 3 is -1 [2,3,4].produce(&[-]).say; # OUTPUT: «(2 -1 -5)» say produce &[-], (2,3,4); # OUTPUT: «(2 -1 -5)» say [\-] (2,3,4); # OUTPUT: «(2 -1 -5)»
A triangle metaoperator [\ ]
provides a syntactic shortcut for producing with an infix operator:
# The following all do the same thing... my @numbers = (1,2,3,4,5); say produce { $^a + $^b }, @numbers; say produce * + *, @numbers; say produce &[+], @numbers; # operator does not need explicit identity say [\+] @numbers; # most people write it this way
The visual picture of a triangle [\
is not accidental. To produce a triangular list of lists, you can use a "triangular comma":
[\,] 1..5; # ( # (1) # (1 2) # (1 2 3) # (1 2 3 4) # (1 2 3 4 5) # )
Since produce
is an implicit loop, it responds to next
, last
and redo
statements inside &with
:
say (2,3,4,5).produce: { last if $^a > 7; $^a + $^b }; # OUTPUT: «(2 5 9)»
In Any§
See primary documentation in context for routine produce
multi method produce(Any:U: & --> Nil) multi method produce(Any:D: &with) multi produce (&with, +list)
This is similar to reduce
, but returns a list with the accumulated values instead of a single result.
<10 5 3>.reduce( &[*] ).say ; # OUTPUT: «150» <10 5 3>.produce( &[*] ).say; # OUTPUT: «(10 50 150)»
The last element of the produced list would be the output produced by the .reduce
method.
If it's a class, it will simply return Nil.
In Supply§
See primary documentation in context for method produce
method produce(Supply:D: &with --> Supply:D)
Creates a "producing" supply with the same semantics as List.produce.
my $supply = Supply.from-list(1..5).produce({$^a + $^b}); $supply.tap(-> $v { say "$v" }); # OUTPUT: «1361015»