【问题标题】:What is Haskell's Stream Fusion什么是 Haskell 的 Stream Fusion
【发布时间】:2010-10-09 08:22:09
【问题描述】:

什么是 Haskell 的 Stream Fusion 以及如何使用它?

【问题讨论】:

标签: list optimization compiler-construction haskell


【解决方案1】:

Logan 指出的论文很棒,但有点难。 (只要问我的学生。)关于“流融合如何工作”的内容也很多,而“流融合是什么以及如何使用它”只有一小部分。

流融合解决的问题是编写的功能代码通常会分配中间列表,例如,要创建一个无限的节点编号列表,您可能会这样写

nodenames = map ("n"++) $ map show [1..]

天真的代码会分配一​​个无限的整数列表[1, 2, 3, ...],一个无限的字符串列表["1", "2", "3", ...],最终分配一个无限的名称列表["n1", "n2", "n3", ...]。分配太多了。

流融合所做的是将nodenames 之类的定义转换为使用递归函数的定义,该函数仅分配结果所需的内容。一般来说,消除中间列表的分配被称为森林砍伐

要使用流融合,您需要编写非递归列表函数,这些函数使用GHC ticket 915mapfoldr 等)中描述的流融合库中的函数on) 而不是显式递归。该库包含所有 Prelude 函数的新版本,这些函数已被重写以利用流融合。显然,这些东西将在下一个 GHC 版本 (6.12) 中使用,但不在当前的稳定版本 (6.10) 中。如果你想使用库 Porges 在他的回答中有一个很好的简单解释。

如果您真的想了解流融合的工作原理,请发布另一个问题 --- 但要困难得多。

【讨论】:

  • 是否有计划将此作为前奏列表的默认行为?
  • 应用$和组合.的融合有区别吗?
  • Prelude 的功能是否以某种方式被标记了,还是什么? IE。为什么它不适用于自制的递归函数?
  • GHC 8.0.2 是否支持 Prelude 中的默认列表融合?
【解决方案2】:

据我所知,与 Norman 所说的相反,流融合没有目前在 GHC 的基础中实现(即,您不能只使用 Prelude 函数)。如需更多信息,请参阅GHC ticket 915

要使用流融合,您需要安装流融合库,导入 Data.List.Stream(您也可以导入 Control.Monad.Stream)并且只使用该模块中的函数而不是 Prelude 函数。这意味着导入 Prelude 会隐藏所有默认列表函数,而不是使用 [x..y] 构造或列表推导。

【讨论】:

    【解决方案3】:

    当 GHC 在 6.12 中默认使用这些新函数时,它们也会以非递归方式实现 [x..y] 和列表推导,这不是正确的吗?因为它们不是正确的行的唯一原因是它们是 internal 并且不是真正用 Haskell 编写的,而是更像关键字,为了速度和/或因为您无法重新定义那个语法。

    【讨论】:

    • [ x .. y ] 不是关键字。在窗帘后面它被转换为enumFromTo x y,所以这并没有什么“神奇”。
    猜你喜欢
    • 2016-02-07
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    相关资源
    最近更新 更多