ここでは、Haskellのtakewhile
と同等のPerl 6を書く方法を示します。
sub take-while (&condition, Iterable \sequence){
my \iterator = sequence.iterator;
my \generator = gather loop {
my \value = iterator.pull-one;
last if value =:= IterationEnd or !condition(value);
take value;
}
# should propagate the laziness of the sequence
sequence.is-lazy
?? generator.lazy
!! generator
}
おそらくdropwhile
の実装を示す必要があります。
sub drop-while (&condition, Iterable \sequence){
my \iterator = sequence.iterator;
GATHER: my \generator = gather {
# drop initial values
loop {
my \value = iterator.pull-one;
# if the iterator is out of values, stop everything
last GATHER if value =:= IterationEnd;
unless condition(value) {
# need to take this so it doesn't get lost
take value;
# continue onto next loop
last;
}
}
# take everything else
loop {
my \value = iterator.pull-one;
last if value =:= IterationEnd;
take value
}
}
sequence.is-lazy
?? generator.lazy
!! generator
}
これらは、単なる取得例です。
リスト/イテラブルにメソッドとして追加する価値があると主張できます。
これらはシーケンスジェネレータの構文で実装できます(ただし、そうしてはいけません)。
sub take-while (&condition, Iterable \sequence){
my \iterator = sequence.iterator;
my \generator = { iterator.pull-one } …^ { !condition $_ }
sequence.is-lazy ?? generator.lazy !! generator
}
sub drop-while (&condition, Iterable \sequence){
my \end-condition = sequence.is-lazy ?? * !! { False };
my \iterator = sequence.iterator;
my $first;
loop {
$first := iterator.pull-one;
last if $first =:= IterationEnd;
last unless condition($first);
}
# I could have shoved the loop above into a do block
# and placed it where 「$first」 is below
$first, { iterator.pull-one } … end-condition
}
彼らはPerl 6の/ Rakudoに追加された場合、彼らはおそらくイテレータクラスで実装されるだろう。
:状態変数で行うことができます
do {
my $x = 0;
{ (++$x)² } …^ * > 100
}
:あなたが求めているものの
(。私はちょうどそれらを行くと追加される場合があります)
直接実装のようなものです
{ (++(state $x = 0))² } …^ * > 100
そして、宣言の外では使用されない状態変数は名前を必要としません。
(スカラー変数は、数値コンテキストで0になる、任意の未定義として開始)
{ (++($))² } …^ * > 100
{ (++$)² } …^ * > 100
匿名状態変数を初期化する必要がある場合、あなたはと組み合わせて定義された、またはオペレータ//
を使用することができますが等しいメタオペレータ=
。あなたは次の値を計算する方法をシーケンスジェネレータを伝える必要はありませんいくつかの簡単な例で
{ (++($ //= 5))² } …^ * > 100
。
このような場合、終了条件を簡素化することもできます。あなたはそれが価値に停止しますを知って場合
say 1,2,4 ...^ 100
# (1 2 4 8 16 32 64)
あなたが安全に終了条件を簡素化することができる唯一の他の時間があります。
say 1, { $_ * 2 } ... 64;
# (1 2 4 8 16 32 64)
say 1, { $_ * 2 } ... 3;
# (1 2 4 8 16 32 64 128 256 512 ...)
がtakeWhileとdropWhile実装例をありがとうとして、それが効果的に同じであるので、 。ジェネレータについて:この場合、名前付き関数を使用することはできないと仮定するのは当然ですか? '{foo(++ $ x)} ...^*> 100'と似ています –
@learningProggedなぜそれは可能ではありませんか?それは実際に使用される意味ではありませんが、私はおそらくコードのゴルフのエントリを書くために他の誰よりもその機能を悪用したとして塩の粒でそれを取る。いくつかの場合 '({foo ++ $} ...^*> 100).lazy'として怠け者としてマークしたいかもしれません –