sách gpt4 ai đã đi

raku - 如何使用定义的生成器构建惰性列表,是否有 "takeWhile"替代方案?

In lại 作者:行者123 更新时间:2023-12-04 22:19:07 27 4
mua khóa gpt4 Nike

Tôi đang đọc perl6intro on lazy lists,这让我对某些事情感到困惑。

拿这个例子:

sub foo($x) {
$x**2
}

my $alist = (1,2, &foo ... ^ * > 100);

会给我 (1 2 4 16 256) ,它会平方相同的数字,直到它超过 100。我希望这给我 (1 4 9 16 25 .. ) ,所以不是平方相同的数字,而是将 x 推进一个数字 1(或另一个给定的“步骤”), foo x ,等等。

在这种特定情况下是否有可能实现这一目标?

我对惰性列表的另一个问题如下:
在 Haskell 中,有一个 takeWhile 函数,在 Perl6 中是否存在类似的东西?

1 Câu trả lời

以下是编写 Perl 6 等效于 Haskell 的 takewhile 的方法。

sub take-while ( &condition, Iterable \sequence ){
my \iterator = sequence.iterator;

my \generator = gather loop {
my \value = iterator.pull-one;
last if value =:= IterationEnd or !condition(value);
take value;
}

# should propagate the laziness of the sequence
sequence.is-lazy
?? generator.lazy
!! generator
}

我可能还应该展示 dropwhile 的实现。

sub drop-while ( &condition, Iterable \sequence ){
my \iterator = sequence.iterator;

GATHER: my \generator = gather {

# drop initial values
loop {
my \value = iterator.pull-one;

# if the iterator is out of values, stop everything
last GATHER if value =:= IterationEnd;

unless condition(value) {
# need to take this so it doesn't get lost
take value;

# continue onto next loop
last;
}
}

# take everything else
loop {
my \value = iterator.pull-one;
last if value =:= IterationEnd;
take value
}
}

sequence.is-lazy
?? generator.lazy
!! generator
}

这些只是刚开始工作的例子。

可以说这些值得作为方法添加到列表/可迭代对象中。

您可以(但可能不应该)使用序列生成器语法实现这些。

sub take-while ( &condition, Iterable \sequence ){
my \iterator = sequence.iterator;
my \generator = { iterator.pull-one } …^ { !condition $_ }
sequence.is-lazy ?? generator.lazy !! generator
}

sub drop-while ( &condition, Iterable \sequence ){
my \end-condition = sequence.is-lazy ?? * !! { False };
my \iterator = sequence.iterator;

my $first;
loop {
$first := iterator.pull-one;
last if $first =:= IterationEnd;
last unless condition($first);
}

# I could have shoved the loop above into a do block
# and placed it where 「$first」 is below

$first, { iterator.pull-one } … end-condition
}

如果将它们添加到 Perl 6/Rakudo,它们很可能会使用 Iterator 类来实现。
(我可能会去添加它们。)

你所要求的直接实现是这样的:

LÀM {
my $x = 0;
{ (++$x)² } …^ * > 100
}

这可以用状态变量来完成:

{ ( ++(state $x = 0) )² } …^ * > 100

并且在声明之外不使用的状态变量不需要名称。
(标量变量以未定义的 Any 开始,在数字上下文中变为 0)

{ (++( $ ))² } …^ * > 100
{ (++$)² } …^ * > 100

如果需要初始化匿名状态变量,可以使用定义或运算符 // 与相等的元运算符 = 结合使用。

{ (++( $ //= 5))² } …^ * > 100

在一些简单的情况下,您不必告诉序列生成器如何计算下一个值。
在这种情况下,结束条件也可以简化。

say 1,2,4 ...^ 100
# (1 2 4 8 16 32 64)

唯一可以安全地简化结束条件的时间是,如果 Biết 它将停止在该值上。

say 1, { $_ * 2 } ... 64;
# (1 2 4 8 16 32 64)

say 1, { $_ * 2 } ... 3;
# (1 2 4 8 16 32 64 128 256 512 ...)

关于raku - 如何使用定义的生成器构建惰性列表,是否有 "takeWhile"替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41194693/

27 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com