Le X
(opérateur croisé) et le [+]
(méta- [ ]
opérateur de réduction avec opérateur additif +
) rendent cela étonnamment facile:
Pour représenter 1 la double sommation ∑³ x = 1 ∑⁵ y = 1 2x + y , vous pouvez procéder comme suit:
[+] 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
Si vous souhaitez créer un sub
pour cela, vous pouvez l'écrire comme suit 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 }
Ou encore simplifier les choses pour
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 ;-)
Notez qu'en le tapant, nous pouvons nous assurer que les plages sont passées, mais en le tapant comme Iterable
plutôt que Range
nous pouvons permettre des séquences de sommation plus intéressantes, comme, disons, ΣΣ (1..∞).grep(*.is-prime)[^99], 1..10, { … }
qui nous permettraient d'utiliser la séquence des 100 premiers nombres premiers.
En fait, si nous le voulions vraiment, nous pourrions aller trop loin et autoriser un opérateur de sommation de profondeur arbitraire, ce qui est rendu plus facile en déplaçant la fonction vers la gauche:
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;
};
Tout comme [+]
résume toutes les valeurs de notre f()
fonction, [X]
calcule la croix de manière itérative, par exemple, fait d' [X] 0..1, 3..4, 5..6
abord 0..1 X 3..4
ou (0,3),(0,4),(1,3),(1,4)
, puis fait (0,3),(0,4),(1,3),(1,4) X 5..6
, ou (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. Désolé, SO ne me laisse pas faire LaTeX, mais vous devriez avoir l'idée. 2. Oui, je sais que c'est une lettre d'indice O et non un zéro, les numéros d'indice ne sont pas des identificateurs valides normalement, mais vous pouvez utiliser Slang :: Subscripts pour les activer.