2009-02-23 37 views
60

什么是Haskell的Stream Fusion,我该如何使用它?什么是Haskell的Stream Fusion

+1

有什么,你需要知道哪些不是已经在[这篇文章](http://www.randomhacks.net/articles/2007/02/10/map-fusion-and-haskell-performance“地图融合:让Haskell快225%“)?如果是这样,你能更具体吗? – 2009-02-23 15:46:51

+0

相关:http://lambda.jstolarek.com/2013/04/haskell-as-fast-as-ca-case-study/ – 2015-10-21 14:01:25

回答

60

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

该流的融合解决的问题是,功能码书面经常分配中间的列表,如创建节点数的无限列表,你可以写

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

天真的代码将分配的无限名单整数[1, 2, 3, ...],字符串的无限列表["1", "2", "3", ...],最后是无限名字列表["n1", "n2", "n3", ...]。这是太多的分配。

什么流融合没有将像nodenames这样的定义翻译成某种使用递归函数的方法,该函数仅分配结果所需的内容。通常,取消中间名单的分配称为森林砍伐

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

如果你真的想要解释流融合是如何工作的,请发表另外一个问题---但这很难。

12

据我所知,与诺曼所说的相反,流融合是而不是目前在GHC的基础上实现(也就是说,你不能只使用前奏功能)。欲了解更多信息,请参阅GHC ticket 915

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

-1

这是不是正确的,当6.12中的GHC默认使用这些新函数时,它们也将以非递归方式实现[x..y]和列表推导?因为他们不是正确的行的唯一原因是他们内部并没有真正写在Haskell,但更像是关键字,出于速度和/或因为你将无法重新定义该语法。