我很难理解为什么以下在 STArray 中查找最小元素的尝试在使用ghc
(7.4.1,无论 -O 级别)编译时会导致堆栈空间溢出,但在以下情况下工作正常ghci
:
import Control.Monad
import Control.Monad.ST
import Control.Applicative
import Data.Array.ST
n = 1000 :: Int
minElem = runST $ do
arr <- newArray ((1,1),(n,n)) 0 :: ST s (STArray s (Int,Int) Int)
let ixs = [(i,j) | i <- [1..n], j <- [1..n]]
forM_ ixs $ \(i,j) -> writeArray arr (i,j) (i*j `mod` 7927)
-- readArray arr (34,56) -- this works OK
-- findMin1 arr -- stackoverflows when compiled
findMin2 arr -- stackoverflows when compiled
findMin1 arr = do
es <- getElems arr
return $ minimum es
findMin2 arr = do
e11 <- readArray arr (1,1)
foldM (\m ij -> min m <$> readArray arr ij) e11 ixs
where ixs = [(i,j) | i <- [1..n], j <- [1..n]]
main = print minElem
注意:切换到STUArray
orST.Lazy
似乎没有任何效果。
STArray
但主要问题是:在 big while inside上实现这种“折叠式”操作的正确方法是什么ST
?