#!/usr/bin/perl
#
# eg15: map for iterators example
#

use strict;
use warnings;
use Function::Parameters qw(:strict);

#
# my $it = upto( $min, $max ):
#	Make an iterator that counts from $min upwards
#	to $max and then fails..
#
fun upto( $n, $max )
{
	return fun {
		return undef if $n > $max;
		return $n++;
	};
}

#
# $it2 = map_i( $op, $it ):
#	Equivalent of map for iterators.
#	Given two coderefs ($op, an operator, and $it, an
#	existing iterator), return a new iterator $it2 which
#	applies $op to each value returned by the inner iterator $it.
#
fun map_i( $op, $it ) :(&$)
{
	return fun {
		my $v = $it->();
		return undef unless defined $v;
		local $_ = $v;
		return $op->($v);
	};
}

my $lim = shift @ARGV || 10;
my $scale = shift @ARGV || 2;

my $c = map_i { $_ * $scale } upto( 1, $lim );

while( my $n = $c->() ) { print "$n,"; }
print "\n";
