什么是Haskell的Stream Fusion,该如何使用?
stack build --ghc-options "-ddump-rule-firings -ddump-rule-rewrites" && find .stack-work/ -name '*dump-rule*'
)。
什么是Haskell的Stream Fusion,该如何使用?
stack build --ghc-options "-ddump-rule-firings -ddump-rule-rewrites" && find .stack-work/ -name '*dump-rule*'
)。
Answers:
Logan指向的论文很棒,但是有点困难。(只问我的学生。)“流融合的工作原理”也很重要,而“流融合是什么以及如何使用它”只是很小一部分。
流融合解决的问题是,编写的功能代码经常分配中间列表,例如,为了创建节点号的无限列表,您可能会编写
nodenames = map ("n"++) $ map show [1..]
天真的代码会分配一个无限的整数列表[1, 2, 3, ...]
,一个无限的字符串列表["1", "2", "3", ...]
,最后是一个无限的名称列表["n1", "n2", "n3", ...]
。分配太多了。
流融合的作用是将类似的定义nodenames
转换为使用递归函数的定义,该递归函数仅分配结果所需的内容。通常,消除中间列表的分配称为砍伐森林。
要使用流融合,您需要编写非递归列表函数,这些函数使用GHC票务915(map
,foldr
等)中描述的流融合库中的函数,而不是显式递归。该库包含所有Prelude函数的新版本,这些函数已被重写以利用流融合。显然,这些内容已计划在下一版GHC(6.12)中使用,但不在当前的稳定版本(6.10)中。如果您想使用库,Porges的回答中有一个很好的简单解释。
如果您实际上想要解释流融合的工作原理,请提出另一个问题-但这要困难得多。
$
和成分之间在融合方面有区别.
吗?
是不是正确的,当GHC在6.12中默认使用这些新功能时,它们也将以非递归方式实现[x..y]并列出理解吗?因为它们不是正确的行,唯一的原因是它们是内部的,并不是真正用Haskell编写的,而是出于速度和/或因为您无法重新定义该语法而更像关键字。
[ x .. y ]
不是关键字。在窗帘的背后,它变成了enumFromTo x y
,因此这没有什么“神奇”的东西。