如何在 Raku 中急切地评估来自 grep 的序列?

Whi*_*ist 11 lazy-evaluation raku

我不明白懒惰/渴望在 Raku 中是如何运作的。更准确地说,如何强制渴望。

我知道无限列表是懒惰的。我不明白的是,一些有结尾的 List 是懒惰的,以及为什么在我的情况下 Eager 方法不起作用。

我有这个例子

raku -e 'say (1..*).grep({ .is-prime })[^100]'
Run Code Online (Sandbox Code Playgroud)

当我想获得前 100 个元素时,它工作正常。但是当我想要更多时,比如 200 个,我无法获得这 200 个元素。

我知道我可以用 for 循环遍历它们。像这样

raku -e 'for (1..*).grep({ .is-prime })[0..200] { .say }'
raku -e '.say for (1..*).grep({ .is-prime })[0..200]'

Run Code Online (Sandbox Code Playgroud)

我想要做的是获取具有与上述相同功能语法的元素。(没有 for 循环的那个)

我试过那些,但没有奏效

raku -e 'say (1..*).grep({ .is-prime })[^200].eager'
raku -e 'say (1..*).grep({ .is-prime })[eager ^200]'
raku -e 'say eager (1..*).grep({ .is-prime })[^200]'

raku -e 'say (1..*).grep({ .is-prime })[0..200].eager'
raku -e 'say (1..*).grep({ .is-prime })[eager 0..200]'
raku -e 'say eager (1..*).grep({ .is-prime })[0..200]'
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我怎么做吗?

Eli*_*sen 14

这与grepor无关eager,而是与.gist创建对象的字符串表示的方法有关,该方法由 调用say。由于要点是供人类使用的,因此它们故意并不总是完整的:在Iterables 中,.gist只显示前 100 个元素:

my @a = ^100;
say @a;
# [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]

my @a = ^101;
say @a;
# [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 ...]
Run Code Online (Sandbox Code Playgroud)

有多种解决方案:您可以使用put代替say,它会调用该Str方法,该方法通常显示所有元素:

my @a = ^101;
put @a;
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Run Code Online (Sandbox Code Playgroud)

或者,如果您想获得技术上正确的表示,您可以调用该.raku方法:

my @a = ^101;
say @a.raku;
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
Run Code Online (Sandbox Code Playgroud)

所以,回到你的例子:

put (1..*).grep({ .is-prime })[^200];
# 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223

say (1..*).grep({ .is-prime })[^200].raku;
# (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223)
Run Code Online (Sandbox Code Playgroud)

幸运的是,有一种更短的方法来获得.raku表示:dd

dd (1..*).grep({ .is-prime })[^200];
# (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223)
Run Code Online (Sandbox Code Playgroud)

dd调用.raku给定的任何内容,并在可能的情况下收集一些额外的调试信息,并将其打印在 STDERR 上。

  • 是的谢谢你 !这正是我想要的。更重要的是,你给了我不止一种方法来做到这一点:) (2认同)
  • 希望这有帮助:-) ...感谢利兹马特! (2认同)
  • @ikegami 我们大多数人注册并不是为了编写百科全书条目,而是为了帮助其他程序员(并反过来得到帮助)。个性化很重要;-)。 (2认同)