#!/usr/bin/perl use strict; use warnings; use Sub::Curried; =head1 Cycle Example This is documented in detail at L Debolaz asked a question in #moose, how to get: a list of numbers like 10,25,50,100,250,500,1000,etc without tracking any other state than the number itself =cut use feature 'say'; # Perl >= 5.10 # use Perl6::Say; # Perl < 5.10 # We want to be able to declare an infinite list of repeated values, for example # (1,2,3,1,2,3,1,2,3) or in this case a list of functions (x2.5, x2, x2, ...) curry cycle (@list) { my @curr = @list; return sub { @curr = @list unless @curr; return shift @curr; }; } # Or use Sub::Section's op(*) curry times ($x,$y) { $x * $y } # like a fold, but returning intermediate values curry scanl ($fn, $start, $it) { my $curr = $start; return sub { my $ret = $curr; $curr = $fn->($curr, $it->()); return $ret; }; } # convert an infinite list into a perl array curry take ($count, $it) { return map { $it->() } 1..$count; } # and finally.. the example in its glory! say for take 12 => (scanl times)->( 10, cycle [2.5, 2, 2] );