【发布时间】:2020-06-12 17:39:08
【问题描述】:
在 Haskell 中,可以像这样定义无限列表:
[1.. ]
如果找到许多描述如何实现无限列表的文章,我就明白它是如何工作的。 但是,我想不出任何理由使用无限数据结构的概念。
谁能给我一个问题的例子,可以通过 Haskell 中的无限列表更容易(或者可能只)解决?
【问题讨论】:
-
我相信有很多很好的答案,但为了帮助您入门,无限数据结构通常允许更简单的定义。考虑
enumerate,它将列表的每个元素放入带有索引的元组中。这可以使用带有索引的辅助函数递归定义,或者更简单地定义为zipWith [0..]。由于 zip 的性质,写[0..]比[0.. length list - 1]更容易和更通用。 -
这只是意味着您不必通过数据生成函数传递停止条件,但可以在最后应用它。一个经典的例子是
take 50 fibonacci,其中fibonacci是根据自身定义的。 -
首先,让我们忽略“数学上无限的事物”(如整数)和“就我的程序而言实际上是无限的事物”(如用户生成的 I/O 流)之间的区别事件。不难看出通用接口在操作两者方面的优势。第一个你可能不会遇到太多,但后者很常见。
-
根据我的经验,无限数据结构的使用频率并不高。不过,有时它们很方便。例如,如果我们正在编写一个语言解释器,
head [var | var <- infiniteListOfVarNames , not (var `freeIn` expression)]是一个用于生成新名称的短代码,它不会出现在expression中。它效率不高,但易于编写和理解。也有类似的情况,需要在满足一定条件的无限多个值中找到“第一个”值,过滤无限列表是非常自然的。 IMO,无限树没那么有用。 -
@cole 我也打算给出
zip [0..]的例子,但坦率地说,这有点肤浅,不仅因为例如Python 的enumerate也能完成这项工作,甚至在 Haskell 中也能完成:当使用Data.Vector时,你会使用indexed而不是 zip。
标签: haskell functional-programming lazy-evaluation