Это не вполне решето, так как является не тестом на простоту, а генератором простых чисел. Но принцип прореживания по каждому новому найденному числу остаётся.
#! /usr/bin/perl use strict; use warnings; use 5.010; use Test::Most; sub next_int { state $i = 2; return $i++; } sub lazy_grep(&$) { my ($filter, $seq) = @_; return sub { my $next; until ($filter->($next = $seq->())) {}; return $next; }; } sub do_sieve { my $f = shift; my $nv = $f->(); return ($nv, lazy_grep { $_[0] % $nv } $f); } sub sieve { state $next_f = \&next_int; my $n; ($n, $next_f) = do_sieve($next_f); return $n; } cmp_deeply([sieve, sieve, sieve, sieve], [2, 3, 5, 7]); cmp_deeply([sieve, sieve, sieve, sieve], [11, 13, 17, 19]); cmp_deeply([sieve, sieve, sieve, sieve], [23, 29, 31, 37]); done_testing;