use Thread 'async';
use Thread::Queue;

sub make_slices {
        my ($n, @avail) = (shift, @{ +shift });

        my ($q, @part, $gen);
        $gen = sub {
                my $pos = shift;        
                if (@part == $n) {
                        
                        
                        $q->enqueue(\@part, \@avail);
                        return;
                }

                
                return if (@part + @avail < $n);

                for my $i ($pos .. @avail - 1) {                
                        push @part, splice @avail, $i, 1;       
                        $gen->($i);                             
                        splice @avail, $i, 0, pop @part;        
                }
        };

        $q = new Thread::Queue;
        (async{ &$gen;                  
                $q->enqueue(undef)      
        })->detach;     

        return $q;
}

my $qa = make_slices(4, [ 0 .. 9 ]);
while (my $a = $qa->dequeue) {
        my $qb = make_slices(2, $qa->dequeue);

        while (my $b = $qb->dequeue) {
                my $rb = $qb->dequeue;
                print "@$a | @$b | @$rb\n";
        }
}