Perl 6のシーケンス/楽堂

Perl 6では、シーケンスを定義するための新しい演算子...が導入されました。 仕組みは次のとおりです。



my @even-numbers := 0, 2 ... *; #   my @odd-numbers := 1, 3 ... *; my @powers-of-two := 1, 2, 4 ... *; #  
      
      





使用例:



 > my @powers-of-two := 1, 2, 4 ... *; 1; 1 > @powers-of-two[^10] 1 2 4 8 16 32 64 128 256 512
      
      







(定義により無限であるREPLで幾何学的シーケンスを定義する場合、行の最後に「1;」を入れます。その結果、REPLは1を出力し、無限ループに入りません。)



無限の「遅延」シーケンスを制限するために、この例では「^ 10」という表記を使用しました。これは「最初の10要素」を意味します。 このようなレコードでは、計算された変数は将来の使用のために保存されます。



シーケンス演算子...は、遅延リストを作成するための強力なツールです。 彼に1つの番号が与えられると、彼はそれからカウントダウンを開始します。 2つを尋ねると、彼はそれらを算術シーケンスと見なします。 3の場合-彼はそれらが算術または幾何学的シーケンスの始まりであるかどうかを確認します-そうであれば、彼はそれらを続けます。



もちろん、多くのシーケンスは算術的でも幾何学的でもありません。 次の番号をシーケンスで定義する関数を明示的に指定できます。



 > my @Fibonacci := 0, 1, -> $a, $b { $a + $b } ... *; 1; 1 > @Fibonacci[^10] 0 1 1 2 3 5 8 13 21 34
      
      







部分-> $ a、$ b {$ a + $ b}は、2つの引数を取り、その合計を返すスイッチブロック(ラムダ関数)です。 シーケンス演算子は、ブロックが受け取る引数の数を計算し、シーケンスの最後から適切な量を渡して次の数を生成します。



これまでのところ、すべての例の末尾にはアスタリスクがあり、「何でも」を意味します。 この場合、リストには終わりがありません。 そこに数字を入力すると、リストの最後になります。



 > 1, 1.1 ... 2 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 > 1, 1.1 ... 2.01 ...  Rakudo ,     ... > (1, 1.1 ... 2.01)[^14] 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3
      
      







最初のリストは自然に終了しますが、2番目のリストはリミッターを通過します。 その結果、無限のリストが得られます-そのため、14個の要素に制限しました。



浮動小数点計算に精通しているプログラマーは、0.1を加算すると必然的にデュースにつながるとは考えられないと不平を言うでしょう。 Perl 6は、このような計算の精度とパフォーマンスを提供するRat mathを使用します。



10,000未満のすべてのフィボナッチ数を見つけなければならない場合、どの数字がシーケンスの最後になるかを計算することは困難です。 幸いなことに、シーケンス式を設定するためのブロックに加えて、境界条件にブロックを使用できます。



 > 0, 1, -> $a, $b { $a + $b } ... -> $a { $a > 10000 }; 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946
      
      







矢印ブロック-> $ a {$ a> 10000}はチェックを作成します。 1つの引数を取り、10000を超えるとtrueを返します。



ただし、10,000未満のすべての数値を取得する必要がありました。 このタスクには、リミッターブロックの代替表記があります。これは、最後の数字をシーケンスに含めないことを示します。



 > 0, 1, -> $a, $b { $a + $b } ...^ -> $a { $a > 10000 }; 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
      
      







「何でも」のクロージャを使用して、このレコードを次のようにやり直すことができます。



 > 0, 1, * + * ...^ * > 10000; 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
      
      







そのような記録は、より明確であるか、より困難です-それはあなた次第です。



さらに、遅延リストを含むリストは、シーケンスの左側にあります。 つまり、バウンディングブロックを使用して、既存の遅延リストの限られた部分を取得できます。



 > my @Fibonacci := 0, 1, * + * ... *; 1; 1 > @Fibonacci ...^ * > 10000 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 > @Fibonacci[30] 832040
      
      







さらに、シーケンス演算子は、数値のみを扱うことに限定されません。 リストの次の要素を計算する独自の関数を設定することにより、必要な要素からリストを構成できます。



All Articles