這工作(作爲啓動):
use List::Gen '*';
iterate{$_%2 ? 3*$_+1 : $_/2}->from(23)->until(sub{$_ == 1 ? (($delay = 1), 0) : $delay})->say();
讓我看看,如果我可以做一個函數出這一點,並讓$delay
安全...
這應該工作,但不因爲函數傳遞給until
被調用兩次(除了第一個值):
use List::Gen '*';
sub after { use feature 'state'; $f = shift(); $f = '$_' . $f unless (ref($f)); sub { state $d; $r = $d; $d = eval $f; $r } }
iterate{ $_%2 ? 3*$_+1 : $_/2 }->from(23)->until(after('==1'))->say;
這適用於雙函數調用:
use List::Gen '*';
sub after { use feature 'state'; $f = shift(); $f = '$_' . $f unless (ref($f)); sub { state($d1,$d2); $r = $d2; $d2 = $d1; $d1 = eval $f; $r } }
iterate{ $_%2 ? 3*$_+1 : $_/2 }->from(23)->until(after('==1'))->say;
仍試圖理解爲什麼until
函數在第一次調用後被調用兩次。
它只適用於until
而不是while
。
上面的代碼只適用於字符串參數;這一個工程與函數引用:
#!/usr/bin/perl
use strict;
use List::Gen '*';
sub after {
use feature 'state';
my $f = shift();
my $c = ref($f) eq 'CODE'
? '&$f()'
: '$_' . $f;
sub {
state($d1,$d2);
my $r = $d2;
$d2 = $d1;
$d1 = eval($c);
$f;
$r
}
}
iterate{$_%2 ? 3*$_+1 : $_/2}->from(23)->until(after('==1'))->say;
iterate{$_%2 ? 3*$_+1 : $_/2}->from(23)->until(after(sub{$_ == 1}))->say;
嗯...有一個很好的功能,但發現後對於相同的值,第一個「while」或「until」調用,隨後的「while」或「until」調用被執行兩次:即23,70,70,35,35,106,106,...,4,4, 2,2,1!參見:'iterate {$ _%2?從(23) - > while(sub {print「_ = $ _ \ n」; $ _!= 1}) - > say;' – kjpires
我想通了,3 * $ _ + 1:$ _/2} - >一個[解決方法](http://stackoverflow.com/a/30664416/133939)感覺更清潔,其中包括在遇到第一個'1'後追加'undef'並測試'defined' -ness – Zaid
如果它不是'對於雙重調用(仍然讓我感到困惑),我可以讓這個延遲函數返回N個附加序列,這對於非終止序列可能是有用的。 – kjpires