2016-10-12 36 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
相关问题