2017-04-13 49 views
8

假設我有一個序列,我知道開始點和結束點,並且生成器很簡單。我可以讓它懶嗎?在Perl 6中可以使用有限的列表嗎?

my @b = 0 ... 3; 
say 'Is @b lazy? ' ~ @b.is-lazy; # Not lazy 

我想組合已知列表與自己未知次數,但不立即生成整個列表。我想@cross偷懶:

my @cross = [X] @b xx $n; 

我知道我可以通過其他簡單的事項或編程(和我的Perl 5 Set::CrossProduct就是這樣做的)做到這一點,但我很好奇,如果有一些簡單的和預期的方式我錯過了。某種方式不涉及我依靠自己的方式。

作爲一個側面問題,序列的特徵是什麼讓它變得懶惰?它只是端點嗎?是否有一個已知端點的序列,如果生成器可以在兩者之間創建無限值,那麼該序列仍然可以是惰性的?我不知道我是多麼的信息必須刪除,並試圖像這樣:

my $m = @*ARGS[0]; 
my @b = 0, * + $m ...^* > 3; 
say 'Is @b lazy? ' ~ @b.is-lazy; 
say '@b: ' ~ @b; 

不過,這更是不可以偷懶。

回答

5

在我看來,「懶惰」的方法確實是一個誤用。正如cuonglm指出的那樣,它說的唯一的東西就是傳遞基礎迭代器聲稱是懶惰的。但那仍然並不意味着什麼,真的。迭代器可以在技術上按需生成值,但仍然聲稱它不是懶惰的。反之亦然。

「is-lazy」檢查在內部用於防止需要事先知道元素數量的情況(如.roll或.pick):如果Seq/iterator聲稱是懶惰的,它會贏得'實際上嘗試,但失敗或拋出。

該.lazy做的唯一的事,是包裹SEQ的迭代器到另一個迭代器,確實權利要求是懶惰(如果給定的迭代器聲稱它是不懶惰,當然)。並確保它不會拉任何值,除非確實需要。所以,添加.lazy並沒有告訴任何關於什麼時候會產生價值的信息,只有當它們將被交付時。它有助於測試基於迭代器的邏輯,看看它們如何與一個聲稱是懶惰的迭代器一起工作。

所以,回到問題:如果你想成爲肯定什麼是懶惰的,你將不得不自己編寫迭代器。話雖如此,在過去的幾個月中,我花了相當多的精力在內核中儘可能地讓事情變得懶散。值得注意的是xx N仍然不是懶惰的,儘管它現在產生了Seq。讓它懶惰打破了一些深刻的spectests,我還沒有弄清楚。展望未來,我認爲你可以肯定事情會像一般意義上的懶惰一樣,也許可能會指出內存優於CPU。但是你永遠不會完全控制內置函數:如果你想完全控制,你必須自己編寫它。

5

是的,你可以使用lazy method

> my @b = (0 ... 3).lazy; 
[...] 
> say 'Is @b lazy? ' ~ @b.is-lazy; 
Is @b lazy? True 

沒有什麼特別Seq,使其偷懶,只是其潛在的Iterator一樣。

+0

呵呵。我確信我嘗試過。謝謝! –

1

正如已經指出的那樣,is-lazy並不代表什麼意思。

但我只是想提一下page on rakudo wiki,它提供了一些關於is-lazy可以預期的線索。

1

您可以:

my @b = 0 ... 3; 

懶惰只是通過增加lazy關鍵字在正確的地方,像這樣:

my @b = lazy 0 ... 3; 

或者,如cuonglm指出的那樣,你可以調用範圍的方法,如下:

my @b = (0 ... 3).lazy; 
相關問題