我刚刚写了一段Haskell代码,为了调试我的代码,在我的代码中放入了一堆打印语句(因此,我的最重要的函数返回IO t
,而它只需要返回t
),我发现这个函数在成功运行时会占用大量内存(大约1.2GB)。一旦我看到程序正常工作,我就从函数中删除了所有的打印语句并运行它,结果发现它给我报错:
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.
尽管代码完全相同,但由于打印语句的存在,它却无视了堆栈溢出。有人能告诉我为什么会发生这种情况吗?
我知道我没有提供代码,这可能会使回答这个问题更难,但我已经把很多东西拼凑在一起,它看起来不太美观,所以我怀疑它并没有什么用处,而且我相当确定唯一的区别就是打印语句。
编辑:
因为人们真的想看到代码,这里是相关部分:
linkCallers :: ([Int], Int, Int, I.IntDisjointSet, IntMap Int) -> ([Int], Int, Int, I.IntDisjointSet, IntMap Int)
linkCallers ([], x, y, us, im) = ([], x, y, us, im)
linkCallers ((a:b:r), x, y, us, im) = if a == b
then (r, x, y+1, us, im)
else if sameRep
then (r, x+1, y+1, us, im)
else (r, x+1, y+1, us', im')
where
ar = fst $ I.lookup a us
br = fst $ I.lookup b us
sameRep = case ar of
Nothing -> False
_ -> ar == br
as' = ar >>= flip lookup im
bs' = br >>= flip lookup im
totalSize = do
asize <- as'
bsize <- bs'
return $ asize + bsize
maxSize = (convertMaybe as') + (convertMaybe bs')
us' = I.union a b $ I.insert a $ I.insert b $ us
newRep = fromJust $ fst $ I.lookup a us'
newRep' = fromJust $ fst $ I.lookup b us'
im'' = case ar of
Nothing -> case br of
Nothing -> im
Just bk -> delete bk im
Just ak -> delete ak $ case br of
Nothing -> im
Just bk -> delete bk im
im' = case totalSize of
Nothing -> insert newRep maxSize im''
Just t -> insert newRep t im''
startLinkingAux' (c,x,y,us,im) = let t@(_,x',_,us',im') = linkCallers (c,x,y,us,im) in
case (fst $ I.lookup primeMinister us') >>= flip lookup im' >>= return . (>=990000) of
Just True -> x'
_ -> startLinkingAux' t
"
startLinkingAux'
曾经长这样:"startLinkingAux' (c,x,y,us,im) = do
print (c,x,y,us,im)
let t@(_,x',_,us',im') = linkCallers (c,x,y,us,im) in
case (fst $ I.lookup primeMinister us') >>= flip lookup im' >>= return . (>=990000) of
Just True -> return x'
_ -> startLinkingAux' t
print
语句强制评估了一个惰性计算的 thunk,没有它,thunk 累积直到溢出堆栈。请参阅此文章以了解如何构建 thunks:http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl' - ErikRDebug.Trace.trace
进行调试。 - augustss