haskell - STArray 和堆栈溢出

标签 haskell stack-overflow starray

我很难理解为什么以下在 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

注意:切换到STUArrayST.Lazy 似乎没有任何效果。

但主要问题是:在 ST 内对大型 STArray 实现此类“类似折叠”操作的正确方法是什么?

最佳答案

这可能是 getElems 是个坏主意的结果。在这种情况下,数组完全不是一个好主意:

minimum (zipWith (\x y -> (x, y, mod (x*y) 7927)) [1..1000] [1..1000])

这个立即给你答案:(1, 1, 1)。

如果无论如何你都想使用数组,我建议先将数组转换为 ArrayUArray,然后再使用 elemsassocs 那个。如果您使用 runSTArrayrunSTUArray 执行此操作,则无需额外费用。

关于haskell - STArray 和堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14471359/

相关文章:

c - Haskell FFi 与 c2hs : Better out-marshalling of structs

haskell - 为数据构造函数提供列表中的元素

haskell - Haskell 中具有运算符优先级和关联性的 pretty-print 语法树

java - 我在这段代码上得到了 StackOverFlowException,因为我的 JVM 不支持尾调用优化,对吧?

java - 在外部类中创建新实例时出现 StackOverflow 错误

arrays - 在数据结构中包含 ST(U) 数组?

haskell - ST-Monad 中的多项更新

haskell - Haskell 中尚未在 GHC 中实现的可能优化?

c# - 循环引用时 .NET 单元测试中的 StackOverflow