Haskell:foldl'累加器参数

我一直在问严格的几个问题,但我认为我之前错过了这个标记。 希望这更准确。

可以说我们有:

n = 1000000
f z = foldl' ((x1, x2) y -> (x1 + y, y - x2)) z [1..n]

不改变f ,我应该设置什么

z = ...

所以fz不会溢出堆栈? (即不管n的大小如何都在恒定的空间中运行)

它可以,如果答案需要GHC扩展。


我的第一个想法是定义:

g (a1, a2) = (!a1, !a2)

接着

z = g (0, 0)

但我不认为g是有效的Haskell。


所以你严格的foldl'只会在折叠的每一步中评估你的lambda的结果为弱头标准形式,也就是说它只在最外层的构造函数中是严格的。 因此,元组将被评估,但是元组内的这些添加可能会形成为thunk。 这个深入的答案实际上似乎解决你在这里的确切情况。

W / R / T你g :你正在考虑BangPatterns扩展,看起来像

g (!a1, !a2) = (a1, a2)

并且在将元素返回给元组之前将a1和a2评估为WHNF。

你想要关心的不是你的初始累加器,而是你的lambda表达式。 这将是一个很好的解决方案:

f z = foldl' ((!x1, !x2) y -> (x1 + y, y - x2)) z [1..n]

编辑 :注意到你的其他问题后,我看到我没有仔细阅读这一个。 可以这么说,你的目标是要有“严格的数据”。 那么你的另一个选择就是创建一个新的元组类型,在其字段上有严格标签:

data Tuple a b = Tuple !a !b

然后,当你在Tuple ab上匹配模式时, ab将被评估。

无论如何你都需要改变你的功能。


没有改变f你就无能为力。 如果f在对中的类型中超载,那么可以使用严格的对,但按照它的规定,你会被锁定到f所做的。 编译器(严格分析和转换)可以避免堆栈增长,但没有什么值得您信赖的。

链接地址: http://www.djcxy.com/p/42983.html

上一篇: Haskell: foldl' accumulator parameter

下一篇: Making a histogram computation in Haskell faster