什么是Haskell的stream融合
什么是Haskell的Stream Fusion,我该如何使用它?
Logan指出的文章很棒,但有点困难。 (只问我的学生。)关于“stream融合如何工作”以及只有一小部分“stream融合是什么以及如何使用它”,这也是一个很大的问题。
stream融合解决的问题是,所编写的function代码经常分配中间列表,例如创build节点数量的无限列表,您可能会写
nodenames = map ("n"++) $ map show [1..]
天真的代码将分配一个无限的整数列表[1, 2, 3, ...]
,一个无限的string列表["1", "2", "3", ...]
,并最终一个无限的列表名称["n1", "n2", "n3", ...]
。 这是太多的分配。
什么stream融合不会将像nodenames
这样的定义转换成使用recursion函数来分配结果所需的东西。 一般来说,取消中间名单的分配称为毁林 。
要使用stream融合,您需要编写非recursion列表函数 ,这些函数使用GHC票证915 ( map
, foldr
等)中描述的stream融合函数库中的函数,而不是显式recursion。 这个库包含所有Prelude函数的新版本,这些函数已经被重写以利用stream融合。 显然这个东西将被定为下一个GHC版本(6.12),但不在当前的稳定版本(6.10)。 如果你想使用库Porges在他的答案有一个很好的简单的解释。
如果你真的想要解释stream融合是如何工作的,可以发表另外一个问题—但这很难。
据我所知,与Norman所说的相反,在GHC的基础上(即不能仅仅使用Prelude函数),stream融合目前还没有实现。 欲了解更多信息,请参阅GHC票915 。
要使用stream融合,你需要安装stream融合库,导入Data.List.Stream(你也可以导入Control.Monad.Stream),只使用该模块的function,而不是Preludefunction。 这意味着导入隐藏所有默认列表函数的前奏,而不是使用[x..y]结构或列表理解。
是不是正确的,当6.12中的GHC默认使用这些新函数时,它们也将以非recursion的方式实现[x..y]和列表parsing? 因为他们不是正确的行的唯一原因是,他们是内部的 ,没有真正写在哈斯克尔,但更像是关键字,出于速度和/或因为你将无法重新定义该语法。