2010-12-20 36 views
3

我已经使用haskell很长一段时间了,我已经阅读了大部分真实世界Haskell并学习了你一个Haskell。我想知道的是,是否对使用懒惰评估的语言有所指向,特别是拥有无限列表的“优势”,是否有无限列表变得非常容易的任务,甚至是只有无限可能的任务名单?无限列表对任何现实世界的应用程序都有用吗?

+0

如果您将博客Web应用程序视为“真实世界应用程序”,则可能不需要无限列表。但是,正如SK-Logic所指出的那样,对于像构建词法分析器这样的更高级的东西来说,它非常方便。 – 2010-12-20 15:42:59

回答

16

下面是一个极其微不足道但实际上每天都会用到的无限列表实际使用的有用示例:当您有要用于初始化某些键值样式数据结构的项目列表时,与连续的键。所以,假设你有一个字符串列表,并且你想把它们放入一个从0开始计数的IntMap。没有懒惰的无限列表,你可以做一些事情,如走下输入列表,保持一个正在运行的“下一个索引”计数器并建立随你去吧IntMap

随着无限的懒惰列表,列表本身承担运行计数器的角色;只需使用zip [0..]与您的物品清单分配索引,然后IntMap.fromList来构建最终结果。

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

13

一个明显的例子就是将数据处理从输入链接到任何你想用它做的事情。例如,将一串字符读入一个懒惰列表,由词法分析器处理,同时产生一个懒惰的令牌列表,这些列表被解析成一个懒惰的AST结构,然后编译并执行。这就像使用Unix管道。

+3

除了这不是一个无限列表,只是一个懒惰的列表。 – 2010-12-20 17:29:57

+2

如果您正在从套接字或管道中读取数据,则从技术角度而言,如果EOF永远不会被读取,那么这在技术上是无限的。内部表示是相似的 - 尾部总是被评估为递归函数。 – 2010-12-20 17:33:01

6

基本上,懒惰列表允许你延迟计算,直到你需要它。如果事先不知道什么时候停止以及需要预先计算什么,这可以证明是有用的。

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

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

  • 计算u_n直到小量/ 2准确性
  • 计算v_n直到小量/ 2准确性
  • 回报u_n + v_n

一切都懒洋洋地做,只有必要的u_n和v_n被计算。你可能想要更简单的例子,例如。计算f(u_n)在你知道的地方(即知道如何计算)f的连续性模数。

8

我发现将一个序列全部定义在一个地方,即使它是无限的,并且使用它的代码只是抓住它想要的,往往更容易和更清晰。

take 10 mySequence 
takeWhile (<100) mySequence 

,而不必大量相似但不产生一个子集

first10ofMySequence 
elementsUnder100ofMySequence 

当同一序列的不同分部在不同的领域中使用的好处是更大的相同的功能。

+0

在我看来,这是它的核心。它在概念上更简单,并导致更干净的代码重用。 – Dan 2010-12-20 17:02:21

3

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

这样做的标准地简单的例子是斐波纳契数列,直接定义为递归关系。 (是的,保持效率投诉/算法讨论 - 点是成语。):fibs = 1:1:zipwith (+) fibs (tail fibs)

这是另一个故事。我有一些只能用于有限数据流的代码 - 它做了一些事情来创建它们,然后做了一大堆废话,这些废话涉及依赖于整个流之前的各个位流,将它与来自另一个流的信息合并等等。这很不错,但是我意识到它有一大堆处理边界条件所必需的信息,基本上当一个信息流用完时,该怎么办。然后我意识到,在概念上,没有理由不能在无限的流中工作。所以我转而使用一种没有零的数据类型 - 即一个真正的流而不是一个清单,所有的垃圾都消失了。尽管我知道我永远不会需要超过某个特定点的数据,但能够依靠它在那里允许我安全地删除大量愚蠢的逻辑,并让我的代码的数学/算法部分更加清晰。

3

声音合成 - 通过耶Karczmarczuk见本文:

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

耶Karczmarcuk具有许多使用无限列表像幂级数和衍生物数学对象模型中的其他文件。

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

6

无限数据结构(包括列表)大大提高了模块性并因此提高了可重用性,如John Hughes的经典论文Why Functional Programming Matters中所解释的&所述。例如,您可以将复杂的代码块分解为生产者/过滤器/消费者件,其中每个块都可能在别处有用。

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

3

我的实用最爱之一是cyclecycle [False, True]生成无限列表[False, True, False, True, False ...]。特别是,xs ! 0 = False,xs ! 1 = True,所以这只是说元素的索引是否是奇数。这显示在哪里?很多地方,但是这里有一个任何Web开发人员都应该熟悉的:制作表格,逐行替换阴影。

这里看到的一般模式是,如果我们想在有限列表上进行一些操作,而不是必须构造一个特定的有限列表来“做我们想要的事情”,我们可以使用一个无限列表适用于所有大小的列表。 Camcann的答案就是这样。

相关问题