use List::Util qw( reduce ); sub seq_prod { no warnings 'once'; reduce { seq_prod2($a,$b) } @_ ; } sub seq_prod2 { my ($s, $t) = @_; my @sval; sub { my @tval; while ( !@sval || !(@tval = $t->()) ) { return () unless @sval = $s->(); } ( @sval, @tval ); }; } sub iter_prod { seq_to_iter( seq_prod( map iter_to_seq($_), @_ ) ); }