2016-10-12 34 views
10

Perl 6有lazy lists,但它也有無限制的對象。你應該選擇哪一個用於統計整數?我應該用Perl 6來計算序列還是範圍?

而且有無限Range有兩點:

0 .. * 

還有的Seq (sequence)有三個點:

0 ... * 

一個Range產生consecutives的名單使用他們的自然順序thingys。它繼承自Iterable,還有Positional,所以你可以索引一個範圍。您可以檢查Range內是否有內容,但這不屬於該任務的一部分。

A Seq只要知道如何進入下一個元素就可以生成任何你喜歡的東西。它繼承自Iterable,還有PositionalBindFailover,它通過緩存和列表轉換來欺騙Positional的東西。如果你只是從一個元素轉向另一個元素,我認爲這不是什麼大不了的事情。

我在這裏來回走動。目前我在想這是Range

+0

對於這樣一個問題,'perl6-language'郵件列表或'#perl6' IRC頻道對於這樣一個問題可能是一個更好的地方... – Christoph

+4

沒有人會在一週後找到答案。人們在Stackoverflow上找到答案。 –

+0

,但stackoverflow應該是更多關於實際問題,而不是關於語言語義錯綜複雜;我懷疑你會對實際答案感到滿意(使用'Range'作爲'..'比'...'短); p);心裏,我很樂意回答這樣的問題,但我不確定它真的適合這裏... – Christoph

回答

8

從語義上講,Range是一個靜態的東西(有界值的集合),一個Seq是一個動態的東西(值發生器)和一個懶惰List動態事物的靜態視圖(生成值的不可變緩存)。

經驗法則:不想靜態對動態,但在複雜的簡單。

此外,Seq是一個迭代的事情,一個List是一個迭代的位置的事情,和Range是一個有序的迭代位置的事情。

經驗法則:使用最通用或最具體的取決於上下文。

由於我們只處理迭代並且對位置訪問或邊界不感興趣,所以使用Seq(本質上是盒裝的Iterator)似乎是一個自然選擇。但是,有序的連續整數集合是,正好是Range表示的整數,並且我個人認爲這是最適合您特定用例的。

當沒有明確的選擇時,無論如何我傾向於選擇範圍來簡化它(儘量避免懶惰列表,重量級)。

注意語言的語法也碰了一下你的Range的方向,這是相當嚴重霍夫曼編碼(兩字符綴..,單字符前綴^)。

+1

@briandfoy:我爲我的偏好添加了一些基本原理 – Christoph

+2

「*反覆總是按Seq的方式發生*」 - 我不認爲'1 .. * {}'構造了一個'Seq'。據我瞭解,'for'循環1)認爲它得到一個'Iterable',2)調用'.iterator'來獲得'Iterator',3)一直調用['.pull-one']( https://docs.perl6.org/type/Iterator#method_pull-one),直到它獲得一個'IterationEnd'。 – smls

+1

@smls:現在希望更好... – Christoph

-2

之間有一個差 「..」(範圍), 「...」(SEQ):

$ perl6 
> 1..10 
1..10 
> 1...10 
(1 2 3 4 5 6 7 8 9 10) 
> 2,4...10 
(2 4 6 8 10) 
> (3,6...*)[^5] 
(3 6 9 12 15) 

的 「...」 操作員可以直覺的圖案!

https://docs.perl6.org/language/operators#index-entry-..._operators

據我瞭解,你可以遍歷序列只有一次。它意味着您不需要返回的流式傳輸(例如文件)。我認爲範圍應該是一個不錯的選擇。

+1

我已經在問題中說過這個問題。 –

10

​​和0 ... *都沒問題。

  • 對它們進行迭代,例如使用for循環,在兩種情況下都具有完全相同的效果。 (通過保持已經迭代的元素都不會泄漏內存。)
  • 將它們分配給@變量會生成相同的惰性數組。

所以,只要你只想把數字加到無窮大的步長爲1,我也沒有看到任何一個缺點。

...序列構建操作者是更通用的,雖然,因爲它也可用於

  • 計數與不同的步驟(1, 3 ... *
  • 計數向下(10 ... -Inf
  • 遵循幾何序列(2, 4, 8 ... *
  • 按照自定義迭代公式(1, 1, *+* ... *

所以,當我需要做這樣的事情,那麼我會考慮使用...任何附近和相關的「一個計數」爲好,以保持一致性。

在另一方面:

  • 一個Range可以有效地索引,而無需生成和緩存所有前面的元素,所以如果你想索引你除了櫃檯遍歷它,它是優選的。處理元素位置的其他列表操作也是如此,例如reverseRange對它們有效的重載,而在Seq上使用它們必須先迭代和緩存其元素。
  • 如果你想向上計數到一個可變的終點(如1 .. $n),使用Range更安全,因爲無論$n是什麼,都可以確保它永遠不會倒數。 (如果端點低於起始點,在1 .. 0,它會表現爲反覆當空序列,這往往讓邊緣案件在實踐中的權利。)
    相反,如果你想安全地算向下保證它會永遠不會意外地向上計數,您可以使用reverse 1 .. $n
  • 最後,Range是「從x到y的數字」概念的更具體/高層表示,而Seq表示「一系列值」的更一般概念。一般來說,Seq是由任意發生器代碼驅動的(參見gather/take) - ...運算符只是用於創建一些常見類型序列的語義糖。因此,當「從x到y的數字」是您想要表達的概念時,使用範圍可能會更具說明性。不過,我想這是一個純粹的心理關注...:P
相關問題