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秒钟,它可能会再次溢出.所以这不是一个解决方案.我怎样才能使这段代码有效?
我编译了这个程序,并试图运行它.
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文件,编译和运行没有任何问题.我想将一些函数和类型定义放在一个通用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)
这是编译的正确方法还是我遗漏了什么?
运行以下程序将打印"空间溢出:当前大小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为简单起见删除定义
我正在通过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) 以下简短的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)