无限列表对任何实际应用程序都有用吗?

时间:2010-12-20 14:59:36

标签: list haskell lazy-evaluation infinite

我现在已经使用haskell很长一段时间了,我已经阅读了大部分真实世界Haskell和了解你的Haskell。我想知道的是,对于使用惰性评估的语言是否有意义,特别是具有无限列表的“优势”,是否有无限列表变得非常容易的任务,或者甚至是只有无限可能的任务列表?

8 个答案:

答案 0 :(得分:16)

这里有一个完全无关紧要但实际上是日常有用的例子,其中无限列表特别派上用场:当你有一个项目列表要用来初始化一些键值式数据结构时,从连续的钥匙。所以,假设你有一个字符串列表,并且你希望将它们放入从0开始的IntMap计数。如果没有懒惰的无限列表,你可以做一些事情,比如走下输入列表,保持一个正在运行的“下一个索引”在你出发时反击并建立IntMap

使用无限的惰性列表,列表本身扮演运行计数器的角色;只需使用zip [0..]和项目列表来分配索引,然后使用IntMap.fromList来构建最终结果。

当然,在这两种情况下,它基本上都是一样的。但是,拥有懒惰的无限列表可以让您更直接地表达概念,而无需担心输入列表的长度或跟踪额外计数器等细节。

答案 1 :(得分:13)

一个明显的例子是将数据处理从输入链接到您想要用它做的任何事情。例如,将字符流读取到由词法分析器处理的惰性列表中,还产生令牌的惰性列表,其被解析为惰性AST结构,然后被编译和执行。这就像使用Unix管道一样。

答案 2 :(得分:8)

我发现在一个地方定义所有序列通常更简单,更清晰,即使它是无限的,并且让使用它的代码只是抓住它想要的东西。

take 10 mySequence
takeWhile (<100) mySequence

而不是有许多相似但不完全相同的函数来生成子集

first10ofMySequence
elementsUnder100ofMySequence

当在不同区域使用相同序列的不同子部分时,益处更大。

答案 3 :(得分:6)

基本上,延迟列表允许您在需要之前延迟计算。如果您事先不知道何时停止以及预先计算什么,这可能会很有用。

标准示例是u_n一系列数值计算收敛到某个极限。您可以要求第一个术语,例如| u_n - u_ {n-1} | &LT; epsilon,为您计算正确的术语数。

现在,您有两个这样的序列u_n和v_n,并且您想知道epsilon精度的限制之和。算法是:

  • 计算u_n直到epsilon / 2准确度
  • 计算v_n直到epsilon / 2准确度
  • return u_n + v_n

所有都是懒惰地完成,只计算必要的u_n和v_n。您可能需要不太简单的示例,例如。计算f(u_n)你知道(即知道如何计算)f的连续模数。

答案 4 :(得分:6)

无限数据结构(包括列表)大大提高了模块性,从而提高了可重用性,正如所解释的那样。在约翰休斯的经典论文Why Functional Programming Matters中有所阐述。 例如,您可以将复杂的代码块分解为生产者/过滤器/消费者块,每个块都可能在其他地方使用。

因此,无论您在代码重用中看到真实世界的价值,您都可以回答您的问题。

答案 5 :(得分:3)

无限/懒惰的结构允许“打结”的成语:http://www.haskell.org/haskellwiki/Tying_the_Knot

这个典型的简单例子是Fibonacci序列,直接定义为递归关系。 (是的,是的,举行效率投诉/算法讨论 - 重点是成语。):fibs = 1:1:zipwith (+) fibs (tail fibs)

这是另一个故事。我有一些代码只适用于有限的流 - 它做了一些事情来创建它们到一定程度,然后做了一大堆废话,涉及在该点之前依赖于整个流对流的各个位进行操作,将它与来自另一个流等的信息合并。这非常好,但我意识到它有一大堆必要的处理边界条件,以及基本上当一个流耗尽时要做什么。然后我意识到,从概念上讲,没有理由不能在无限流上工作。所以我切换到没有零的数据类型 - 即一个真正的流而不是列表,所有的瑕疵都消失了。即使我知道我永远不会需要超过某一点的数据,能够依靠它在那里允许我安全地删除许多愚蠢的逻辑,并让我的代码的数学/算法部分更加突出。 / p>

答案 6 :(得分:3)

声音合成 - 请参阅Jerzy Karczmarczuk的论文:

http://users.info.unicaen.fr/~karczma/arpap/cleasyn.pdf

Jerzy Karczmarcuk还有许多其他论文使用无限列表来模拟幂函数和导数等数学对象。

我已将基本声音合成代码翻译成Haskell - 足以用于正弦波单元生成器和WAV文件IO。性能几乎足以在1.5GHz Athalon上运行GHCi - 因为我只是想测试我从未接受过优化它的概念。

答案 7 :(得分:3)

我务实的最爱之一是cyclecycle [False, True]生成无限列表[False, True, False, True, False ...]。特别是xs ! 0 = Falsexs ! 1 = True,所以这只是说元素的索引是否为奇数。这出现在哪里?很多地方,但这是任何网络开发人员应该熟悉的地方:制作表格,从一行到另一行交替着色。

这里看到的一般模式是,如果我们想在有限列表上做一些操作,而不是必须构建一个“做我们想做的事情”的特定有限列表,我们就可以使用一个无限的列表来工作适用于各种规模的清单。 camcann的答案是这样的。