Perl 6のWhatever

5425 ワード

何だ?
Placeholder for unspecified value/parameter-指定されていない値/パラメータのプレースホルダ.*字面量「term」位置に「Whever」オブジェクトを作成します.*の魔法の大部分は「Whateverコリー化」から来ている.*をitemとして多くのオペレータと組み合わせて使用すると、コンパイラは式を「WhateverCode」タイプの閉パッケージに変換する.
my $c = * + 2;          # same as   -> $x { $x + 2 };
say $c(4);              # 6

式にN個の*がある場合、N個のパラメータを含む閉パケットが生成されます.
my $c = * + *;          # same as   -> $x, $y { $x + $y }

複雑な式で*を使用すると、閉パッケージも生成されます.
my $c = 4 * * + 5;      # same as   -> $x { 4 * $x + 5 }
*号でメソッドを呼び出すと、閉パッケージも生成されます.
.map: *.uc;      # same as.map: -> $char { $char.uc }

前述したように、すべてのオペレータや文法が*コリーを「WhateverCode」に変えるわけではありません.次のような場合、*は依然として「Whateverオブジェクト」です.
                 Example    What it does

                 1,*,2          *        Parcel
              1..*       Range.new(:from(1), :to(*));
              1 ... *        
               1 ~~ *        True
                 $x = *       *     $x
                 $x := *      *     $x
               1 xx *           

範囲オペレータは特殊に処理する.Whatever-Starsコリー化は使用しませんが、「WhateverCode」を使用してコリー化します.
say (1..*).WHAT;        # Range
say (1..*-1).WHAT;      # WhateverCode

上の*-1はパラメータとして渡されています.
以下にも使用できます.
.say for 1..*;          # infinite loop
my @a = 1..4;
say @a[0..*];           # 1 2 3 4
say @a[0..*-2];         # 1 2 3

Whatever-curryingは純粋な構文コンパイラ変換なので、実行時に記憶されているWhatever-starsコリーをWhateverCodesに変えることはありません.
my $x = *;
$x + 2;                 # not a closure, dies because
                        # it can't coerce $x to Numeric

格納Whever-starsの使用例は前述の通りであるが,コリー化異常の場合も含める.たとえば、デフォルトの無限シーケンスが必要な場合は、次のようにします.
my $max    = potential-upper-limit() // *;
my $series = known-lower-limit() ... $max;

1つの記憶された*は、スマートマッチングの特殊な状況下でWhateverCodeを生成する.コリー化されているのは、実際に貯蔵されている*ではなく、LHS上の*であることに注意してください.
my $constraint = find-constraint() // *;
my $maybe-always-matcher = * ~~ $constraint;

この仮定のfind-constraintに制約が見つからない場合、maybe-always-matcherは何に対してもTrueに戻る.
$maybe-always-matcher(555);      # True
$maybe-always-matcher(Any);      # True

Whatever Star
「アイテム」として使用する場合、*を「Whatever」と呼びます.実際の値でない場合は、プレースホルダとして使用されます.例えば、1, 2, 3 ... *は、終端点のない自然数シーケンスを意味する.
Whatever閉パッケージ
Whateverの最も強力な用途は「Whatever」の閉鎖です.
Whateverには特別な意味を持たない通常のオペレータ:Whateverをパラメータとして渡すと閉じたパッケージが作成されます!例を挙げてみましょう
* + 1 #     -> $a { $a + 1 }
* + * #     -> $a, $b { $a + $b }

1つの星が1つの穴を占めている.
@list.grep(* > 10)                  #    @list         10    
@list.grep( -> $ele { $ele > 10 } ) #   ,        
@list.grep: -> $ele { $ele > 10 }   #   ,         
@list.grep: * > 10                  #   
@list.grep: { $_ > 10 }             #   


@list.map(* + *)                    #    @list           
@list.map( -> $a, $b { $a+$b } )    #   ,        
@a[ ]の括弧の中に閉パケットを渡すと、@a配列の要素の個数をパラメータとして渡して計算します.
配列の最後の要素
my @a =  1,22,33,11;
say @a[*-1];
say @a[->$a {$a-1}]; # $a      @a      

配列の最後から2番目の要素
say @a[*-2];
say @a[->$a {$a-2}];

したがって、@a[*/2]@a配列の中間要素であり、@a[1..*-2]@a中に最初の要素を含まない他の要素である.1, 1, * + * ... *は無限のリストであり、* + *は後の値の生成規則であり、最後の*はテストの終了がないことを示す.
閉パケットをスカラーに格納する
my $a = -> $b { $b + 1 }
$a(3) # 4

my @add_by_one = @list.map($a); #   @list         1

Perl 6のリストの評価は不活性で、最後の要素を要求しない限り、無限のリストは問題ありません.バインディング(:=)オペレータを使用して、リストを変数に割り当てます.
my @fib := 1, 1, * + * ... *

後で@fib[40]の値を求めると、配列の41番目の要素を取得するのに十分な要素が生成され、生成された要素が記憶されます.将来的には、リストが変数にバインドされていない場合、以前の値は忘れられ、ほとんどのPerl 6リスト関数が不活性リストを生成します.@a.mapおよび@a.grepは、@aが不活性でなくても「不活性リスト」を生成する.@fib.grep(* %% 2)は偶数の不活性リストであり、例えば@fib Z @aは、@fib[0], @a[0], @fib[1], @a[1] ...の不活性リストを生成する.forループに無限のリストを渡すのは問題なく、停止するまでループします.
ただし、ネストされた閉パッケージは使用できません.
my @a = 1 .. 10;
my @b = @a.map: { * ** 2 }
===SORRY!=== Error while compiling:
Malformed double closure; WhateverCode is already a closure without curlies, so either remove the curlies or use valid parameter syntax instead of * at line 2 ------> 

上記のエラーメッセージに注意してください.明らかに、WhateverCodeはカッコをつけない閉パッケージです.したがって、カッコを削除するか、*号の代わりに合法的なパラメータ構文を使用するか、ヒント情報は十分に明確です.では、ヒントに従います.
方法1:$_号の代わりに*を使用する
> my @b = @a.map: { $_ ** 2 }
[1 4 9 16 25 36 49 64 81 100]

方法2:
> my @b = @a.map:  * ** 2
[1 4 9 16 25 36 49 64 81 100]

方法3、closureを明示的に使用する:
> my @b = @a.map: -> $item { $item ** 2 }
[1 4 9 16 25 36 49 64 81 100]