Haskell 推理懒惰

Haskell 推理懒惰,haskell,lazy-evaluation,Haskell,Lazy Evaluation,我有以下片段: import qualified Data.Vector as V import qualified Data.ByteString.Lazy as BL import System.Environment import Data.Word import qualified Data.List.Stream as S histogram :: [Word8] -> V.Vector Int histogram c = V.accum (+) (V.replicate 2

我有以下片段:

import qualified Data.Vector as V
import qualified Data.ByteString.Lazy as BL
import System.Environment
import Data.Word
import qualified Data.List.Stream as S

histogram ::  [Word8] -> V.Vector Int
histogram c = V.accum (+) (V.replicate 256 0) $ S.zip (map fromIntegral c) (S.repeat 1)

mkHistogram file = do
  hist <- (histogram . BL.unpack) `fmap` BL.readFile file
  print hist
导入限定数据。向量为V
将限定数据.ByteString.Lazy导入为BL
导入系统。环境
导入数据.Word
将符合条件的Data.List.Stream作为S导入
直方图::[Word8]->V.向量整数
直方图c=V.accum(+)(V.replicate 256 0)$S.zip(从积分c映射)(S.repeat 1)
mkHistogram file=do

hist我认为问题在于
Data.Vector
的元素不严格。因此,尽管您的推理是正确的,但当累积直方图时,您的thunks看起来如下:

<1+(1+(1+0)) (1+(1+0)) 0 0 (1+(1+(1+(1+0)))) ... >

而不是

<3 2 0 0 4 ...>


只有当你打印的时候,这些总和才会被计算出来。我在文档中没有看到一个严格的
acum
函数(羞耻),也没有任何地方可以挂接
seq
。摆脱这种困境的一种方法可能是改用
Data.Vector.unbox
,因为unbox类型是unfleed的。也许您可以请求一个严格的
acum
函数,并将您的示例作为一个用例。

这可能有助于您使用
fmap
。更酷,但需要额外的导入,更难键入。但我同意冷静的因素:帕格,卢基击败了我。根据我的测试,只需更改为使用
Data.Vector.unbox
即可使此代码在恒定内存中运行。我使用了
zip
repeat
的前奏定义,而不是
Data.List.Stream
,但我认为这在这种情况下没有任何区别。太好了,这很有帮助。我怀疑这可能是因为accum(或它附近的某个地方)不严格,但不确定如何检查它。@Masse-您收到的堆栈溢出错误是一个很大的线索。堆栈溢出通常是由构造大型thunk导致的,例如,某些东西不够严格,而算术是常见的罪魁祸首。