Seq 已经在使用/消耗(嵌套的 gather / take )

Hol*_*lli 9 raku

sub f()
{
    gather
    {
        take gather { take 3; take 4; take 5; }
        take gather { take 1; take 2; take 3; }
    }
}

say f.sort
Run Code Online (Sandbox Code Playgroud)

与

The iterator of this Seq is already in use/consumed by another Seq
(you might solve this by adding .cache on usages of the Seq, or
by assigning the Seq into an array)
  in block <unit> at so.raku line 1
Run Code Online (Sandbox Code Playgroud)

然而

sub f()
{
    gather
    {
        take cache gather { take 3; take 4; take 5; }
        take cache gather { take 1; take 2; take 3; }
    }
}

say f.sort
Run Code Online (Sandbox Code Playgroud)

按预期工作并产生((1, 2 ,3), (3, 4, 5)). 没关系(感谢 raiph)。现在

sub MAIN( *@n )
{
    @n = @n || ( 3, 4, 5, -1, 111, 27, 28, 29, 1, 2 );

    chunks( @n, { $^left < $^right } )
        .sort({ [*] |$_ })
        .tail
        .say;
}

sub chunks( Iterable $list, &condition )
{
    my $windows = $list.rotor( 2 => -1, :partial ).iterator;
    my $done    = False;

    gather until $done
    {
        my Mu $window := $windows.pull-one;

        last if $window =:= IterationEnd;

        take cache gather
        {
            my $condition-result;

            while $window := $window // $windows.pull-one
            {
                $done = True and last if $window =:= IterationEnd;

                take $window[0];

                $condition-result = &condition( |$window )
                    if $window.elems == 2;

                $window := Any;
                last unless $condition-result;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该产生(27 28 29),但它没有。它产生 (111). 但是当我替换它时take cache gather,take eager gather它会按预期工作。

我的chunks函数与上面更简单的示例具有相同的结构,我认为但行为似乎有所不同。

Mas*_*ssa 6

问题似乎出在您的take gather构造中。它把(仍然打开)Seqs 放在你的大外层里面Seq。我认为,我通过替换take gather为“修复”了您的代码take my @x = gather,一切都按您的意愿工作。


rai*_*iph 6

完全重写

存在三种可能的情况。

在所有这些中,take eager gather是解决方案而不是take gather.

这留下了最外面的gather.

你可以保持原样。这意味着如果您将chunks调用结果绑定到一个变量,然后对其进行两次迭代操作,则会Seq is already in use/consumed出现错误。

或者你可以处理这个问题。您有两种选择,具体取决于您更喜欢chunks急切还是懒惰的操作。如果您希望它急切,请将外部写gather为eager gather. 如果你想让它偷懒,把它写成cache gather.