Der X
( [+]
Kreuzoperator ) und der (Reduktionsmetaoperator [ ]
mit additivem Operator +
) machen dies überraschend einfach:
Um 1 die Doppelsummation ∑³ x = 1 ∑⁵ y = 1 2x + y darzustellen , können Sie Folgendes tun:
[+] do for 1..3 X 1..5 -> ($x, $y) { 2 * $x + $y }
# for 1..3 X 1..5 # loop cross values
# -> ($x, $y) # plug into x/y
# { 2 * $x + $y } # calculate each iteration
# do # collect loop return vals
# [+] # sum them all
Wenn Sie ein dafür erstellen sub
möchten, können Sie es wie folgt schreiben: 2
sub ΣΣ (
Int $aₒ, Int $aₙ, # to / from for the outer
Int $bₒ, Int $bₙ, # to / from for the inner
&f where .arity = 2 # 'where' clause guarantees only two params
) {
[+] do for $aₒ..$aₙ X $bₒ..$bₙ -> ($a, $b) { &f(a,b) }
}
say ΣΣ 1,3, 1,5, { 2 * $^x + $^y }
Oder vereinfachen Sie die Dinge noch mehr
sub ΣΣ (
Iterable \a, # outer values
Iterable \b, # inner values
&f where .arity = 2) { # ensure only two parameters
[+] do f(|$_) for a X b
}
# All of the following are equivalent
say ΣΣ 1..3, 1..5, -> $x, $y { 2 * $x + $y }; # Anonymous block
say ΣΣ 1..3, 1..5, { 2 * $^x + $^y }; # Alphabetic args
say ΣΣ 1..3, 1..5, 2 * * + * ; # Overkill, but Whatever ;-)
Beachten Sie, dass wir durch die Eingabe sicherstellen können, dass Bereiche übergeben werden, aber durch Eingabe als, Iterable
anstatt Range
interessantere Summationssequenzen zuzulassen, wie zum Beispiel, ΣΣ (1..∞).grep(*.is-prime)[^99], 1..10, { … }
dass wir die Sequenz der ersten 100 Primzahlen verwenden würden.
Wenn wir wirklich wollten, könnten wir sogar über Bord gehen und einen beliebigen Tiefensummierungsoperator zulassen, der am einfachsten gemacht wird, indem die Funktion nach links verschoben wird:
sub ΣΣ (
&function,
**@ranges where # slurp in the ranges
.all ~~ Iterable && # make sure they're Iterables
.elems == &function.arity # one per argument in the function
) {
[+] do function(|$_) for [X] @ranges;
};
Berechnet genau wie [+]
alle Werte unserer f()
Funktion [X]
das Kreuz iterativ, z. B. [X] 0..1, 3..4, 5..6
zuerst 0..1 X 3..4
oder (0,3),(0,4),(1,3),(1,4)
und dann (0,3),(0,4),(1,3),(1,4) X 5..6
oder (0,3,5),(0,4,5),(1,3,5),(1,4,5),(0,3,6),(0,4,6),(1,3,6),(1,4,6)
.
1. Entschuldigung, SO lässt mich LaTeX nicht machen, aber Sie sollten auf die Idee kommen. 2. Ja, ich weiß, dass dies ein tiefgestellter Buchstabe O ist, keine Null. Indexnummern sind normalerweise keine gültigen Bezeichner, aber Sie können Slang :: Subscripts verwenden , um sie zu aktivieren.