相关疑难解决方法(0)

如何避免Haskell中的堆栈溢出?

Haskell不支持循环计算,而是提供使用递归算法.但是这种方法导致堆栈增长,甚至堆栈溢出.我认为应该有办法解决这个问题.这是样本.我想知道,每5秒可以调用多次getClockTime:

import System.Time

nSeconds = 5

main = do
    initTime <- totalPicoSeconds `fmap` getClockTime
    doWork initTime 1
    where
    doWork initTime n = do
        currTime <- totalPicoSeconds `fmap` getClockTime
        if (currTime - initTime) `div` 10 ^ 12 >= nSeconds
            then print n
            else doWork initTime (n+1)

totalPicoSeconds :: ClockTime -> Integer
totalPicoSeconds (TOD a b) = a * 10 ^ 12 + b
Run Code Online (Sandbox Code Playgroud)

该程序耗时5秒,但最终我得到了:

堆栈空间溢出:当前大小为8388608字节.
使用`+ RTS -Ksize -RTS'来增加它.

在特定情况下,手动管理堆栈大小可能有所帮助,但如果我希望运行此算法10秒钟,它可能会再次溢出.所以这不是一个解决方案.我怎样才能使这段代码有效?

stack-overflow recursion haskell

18
推荐指数
1
解决办法
3030
查看次数

Haskell空间溢出

我编译了这个程序,并试图运行它.

import Data.List
import Data.Ord
import qualified Data.MemoCombinators as Memo

collatzLength :: Int -> Int
collatzLength = Memo.arrayRange (1, 1000000) collatzLength'
  where
    collatzLength' 1 = 1
    collatzLength' n | odd n  = 1 + collatzLength (3 * n + 1)
                     | even n = 1 + collatzLength (n `quot` 2)

main = print $ maximumBy (comparing fst) $ [(collatzLength n, n) | n <- [1..1000000]]
Run Code Online (Sandbox Code Playgroud)

我从GHC获得以下内容

Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it. …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

9
推荐指数
3
解决办法
2943
查看次数

在不同的hs文件中分离函数时,堆栈空间溢出

我有一个巨大的haskell文件,编译和运行没有任何问题.我想将一些函数和类型定义放在一个通用hs文件中的单独模块中,然后将其导入到我的主模块中.虽然主程序编译没有任何错误(它也编译导入的模块),但当我尝试运行它时,我得到一个堆栈空间溢出.

我试过了:

ghc --make -O2 Main.hs
./Main -- stack space overflow
Run Code Online (Sandbox Code Playgroud)

也:

ghc --make -O2 Main.hs Other.hs -o RunMe
./RunMe -- again, stack space overflow
Run Code Online (Sandbox Code Playgroud)

这是编译的正确方法还是我遗漏了什么?

haskell

5
推荐指数
2
解决办法
166
查看次数

如何解决haskell中的"堆栈空间溢出"

运行以下程序将打印"空间溢出:当前大小8388608字节".我已经读过这个这个,但仍然不知道如何解决我的问题.我正在使用foldr,不应该保证它是"尾递归"吗?

到目前为止,我对Haskell感觉很棒,直到我知道在使用强大的递归时我应该防止"空间溢出".:)

module Main where
import Data.List

value a  b = 
  let l = length $ takeWhile (isPrime) $ map (\n->n^2 + a * n + b) [0..]
  in (l, a ,b)

euler27 = let tuple_list = [value a b | a <-[-999..999] , b <- [-999..999]]
      in foldr (\(n,a,b) (max,v) -> if n > max then (n , a * b) else (max ,v) ) (0,0) tuple_list
main = print euler27
Run Code Online (Sandbox Code Playgroud)

编辑:isPrime为简单起见删除定义

recursion haskell lazy-evaluation

4
推荐指数
1
解决办法
2594
查看次数

计算素数时堆栈空间溢出

我正在通过Real World Haskell工作(我在第4章)并且练习了一下我已经创建了以下程序来计算第n个素数.

import System.Environment

isPrime primes test = loop primes test
    where
        loop (p:primes) test
            | test `mod` p == 0 = False
            | p * p > test = True
            | otherwise = loop primes test


primes = [2, 3] ++ loop [2, 3] 5
    where 
        loop primes test
            | isPrime primes test = test:(loop primes' test')
            | otherwise = test' `seq` (loop primes test')
            where
               test' = test + 2
               primes' = primes ++ [test]

main :: …
Run Code Online (Sandbox Code Playgroud)

primes haskell

4
推荐指数
1
解决办法
323
查看次数

堆栈空间溢出ST monad

以下简短的Haskell程序用于计算文件中的项目列表.使用的版本foldl'工作正常,但使用的版本ST Monad给出了堆栈空间溢出消息.显然这里有一些空间泄漏,但我无法解决它.真正有趣的部分是ST monad应该进行就地更新,不应该让资源像这样增长,尽管这可能只涉及主内存而不是堆栈空间.有人能解释一下这里发生了什么吗?

import Control.Monad
import Data.List
import Control.Monad.ST
import Data.STRef

--count items using foldl' 
countFold :: Num a => [b] -> a
countFold = foldl' (\a _ -> a+1) 0

-- count items using the ST monad
-- derived fromt the sumST example on http://www.haskell.org/haskellwiki/Monad/ST
-- only using +1 instead of adding the values
countST :: Num a => [b] -> a
countST xs = runST $ do

    n <- newSTRef 0

    forM_ …
Run Code Online (Sandbox Code Playgroud)

monads haskell lazy-evaluation fold

3
推荐指数
1
解决办法
216
查看次数