Haskell 的流融合是什么?如何使用它?
Haskell 的流融合是什么?如何使用它?
Logan提到的那篇论文很好,但有点难。 (问问我的学生就知道了。) 它也很大程度上是关于“流融合的工作原理”,只涉及一小部分“什么是流融合以及如何使用它”。
流融合解决的问题是,函数式代码通常会分配中间列表,例如,为了创建一个无限节点数列表,您可能会编写:
nodenames = map ("n"++) $ map show [1..]
简单的代码会分配无限整数列表[1, 2, 3, ...]
,无限字符串列表["1", "2", "3", ...]
,以及最终的无限名称列表["n1", "n2", "n3", ...]
。这样分配太多了。
流融合所做的是将类似于nodenames
的定义转化为使用递归函数的东西,该函数仅为结果分配所需的内容。通常,消除中间列表的分配称为deforestation。
要使用流融合,您需要编写非递归列表函数,使用来自流融合库的函数进行描述,该库在GHC ticket 915中进行了介绍(例如map
、foldr
等),而不是使用显式递归。该库包含所有Prelude功能的新版本,这些功能已被重新编写以利用流融合。显然,这个东西计划加入下一个GHC发行版(6.12),但不在当前的稳定版本(6.10)中。如果要使用该库,请查看Porges在他的答案中提供的简单解释。
如果您需要有关如何使用流融合的说明,请发布另一个问题-但那要困难得多。
$
和组合 .
之间的融合有什么区别吗? - CMCDragonkai当 GHC 在 6.12 中默认使用这些新函数时,它们也会以非递归方式实现 [x..y] 和列表推导吗?因为它们现在不是这样的唯一原因是它们是 内部 的,而不是真正用 Haskell 编写的,更像是关键字,出于速度和/或因为您无法重新定义该语法。
[ x .. y ]
不是关键字。在幕后,它被转换为 enumFromTo x y
,因此没有什么“神奇”的地方。 - Willem Van Onsem