我想做以下几件事:
[2,4,3,7,9,3]
[2,6,9,6,5,8]
[2,8,7,3,8,6]
[2,0,7,0,8,4]
字符串
也就是说,在每个阶段中,我想模块化地(在这种情况下为10)将从列表开始到当前位置的所有值相加,创建一个新列表:[2, (2+4)
mod10, (2+4+3)
mod10, (2+4+3+7)
mod10...]
,我想多次调用它。
我的代码是:
applyMulti :: Int -> [Int] -> [Int]
applyMulti 0 dat = dat
applyMulti n dat = applyMulti (n - 1) $ apply dat
apply :: [Int] -> [Int]
apply dat = scanl1 (\a x -> (a + x) `mod` 10) dat
型
这对于小数据和小重复计数很好。但是当一个500k Int的列表运行100次时,它会耗尽内存,程序就会被杀死。我不明白为什么即使500k * 100
也不应该太大,但编译器甚至可以优化它。
我还尝试了一个非尾递归的版本:
applyMulti n dat = apply . applyMulti (n - 1) $ dat
型
我甚至使用了:
{-# LANGUAGE BangPatterns, StrictData, Strict #-}
型
我的错误是什么,我应该如何解决这个问题?
1条答案
按热度按时间vuktfyat1#
我不能复制。内存可能会增加200兆字节,其中包括
ghci
运行时本身。我们可以使用
scanl
的 strict 版本来提高内存使用率:**scanl' :: (b -> a -> b) -> b -> [a] -> [b]
**这将强制计算scanl
枚举的列表项:字符串