简体   繁体   English

什么是Haskell的Stream Fusion

[英]What is Haskell's Stream Fusion

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

The paper that Logan points to is great, but it's a little difficult. Logan指出的论文很棒,但有点困难。 (Just ask my students.) It's also a great deal about 'how stream fusion works' and only a fraction 'what stream fusion is and how you can use it'. (只要问问我的学生。)这也是关于“流融合如何工作”以及“流融合是什么以及如何使用它”的一小部分。

The problem that stream fusion solves is that functional codes as written often allocate intermediate lists, eg, to create an infinite list of node numbers, you might write 流融合解决的问题是写入的功能代码经常分配中间列表,例如,创建无限的节点号列表,您可能会写

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

Naive code would allocate an infinite list of integers [1, 2, 3, ...] , an infinite list of strings ["1", "2", "3", ...] , and eventually an infinite list of names ["n1", "n2", "n3", ...] . 朴素代码将分配一个无限的整数列表[1, 2, 3, ...] ,一个无限的字符串列表["1", "2", "3", ...] ,最终是一个无限的列表names ["n1", "n2", "n3", ...] That's too much allocation. 分配太多了。

What stream fusion does is translate a definition like nodenames into something which uses a recursive function that allocates only what is needed for the result. 流融合的作用是将类似nodenames的定义转换为使用递归函数的东西,该递归函数仅分配结果所需的内容。 In general, eliminating allocation of intermediate lists is called deforestation . 一般而言,取消中间名单的分配称为砍伐森林

To use stream fusion, you need to write non-recursive list functions that use the functions from the stream-fusion library described in GHC ticket 915 ( map , foldr , and so on) instead of explicit recursion. 要使用流融合,您需要编写非递归列表函数 ,这些函数使用GHC ticket 915mapfoldr等)中描述的流融合库中的函数而不是显式递归。 This library contains new versions of all the Prelude functions which have been rewritten to exploit stream fusion. 该库包含所有Prelude函数的新版本,这些函数已被重写以利用流融合。 Apparently this stuff is slated to make it into the next GHC release (6.12) but is not in the current stable version (6.10). 显然,这些东西将进入下一个GHC版本(6.12),但不是当前的稳定版本(6.10)。 If you want to use the library Porges has a nice simple explanation in his answer. 如果你想使用库Porges在他的回答中有一个很好的简单解释。

If you actually want an explanation of how stream fusion works, post another question---but that's much harder. 如果你真的想要解释流融合是如何工作的,那就发布另一个问题---但这要难得多。

As far as I am aware, and contrary to what Norman said, stream fusion is not currently implemented in GHC's base (ie. you cannot just use Prelude functions). 据我所知,与Norman所说的相反,流融合目前还没有在GHC的基础上实现(即你不能只使用Prelude函数)。 For more information see GHC ticket 915 . 有关更多信息,请参阅GHC 915号机票

To use stream fusion you need to install the stream-fusion library, import Data.List.Stream (you can also import Control.Monad.Stream) and only use functions from that module rather than the Prelude functions. 要使用流融合,您需要安装流融合库,导入Data.List.Stream(您也可以导入Control.Monad.Stream)并仅使用该模块中的函数而不是Prelude函数。 This means importing the Prelude hiding all the default list functions, and not using [x..y] constructs or list comprehension. 这意味着导入Prelude隐藏所有默认列表函数,而不是使用[x..y]构造或列表推导。

Isn't it correct, that when GHC in 6.12 uses those new functions by default, that they will also implement [x..y] and list comprehensions in that non-recursive manner? 这是不正确的,当6.12中的GHC默认使用这些新函数时,它们还会以非递归方式实现[x..y]和列表推导吗? Because the only reason they aren't right row, is that they are internal and not really written in Haskell, but more like keywords, for speed's sake and/or because you wouldn't be able to redefine that syntax. 因为它们不是正确行的唯一原因是它们是内部的而不是真正用Haskell编写的,但更像是关键字,为了速度和/或因为你无法重新定义该语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM