haskell - 生成具有恒定堆栈空间的随机向量

标签 haskell stack-overflow monads lazy-evaluation

我正在使用软件包 System.Random.Mersenne.Pure64Control.Monad.Mersenne.Random由 Don Stewart 撰写,通常速度极快,并且是 supposed to help avoid common errors ,比如使用非严格的状态单子(monad)。

尽管如此,我还是设法编写了一些代码,导致中等大向量的堆栈溢出。

import qualified Data.Vector.Unboxed as U
import Data.Int
import System.Random.Mersenne.Pure64
import Control.Monad.Mersenne.Random

main = do
    let dim = 1000000
        y = evalRandom (U.replicateM dim getInt64) (pureMT 13) :: U.Vector Int64
    putStr $ (show $ U.head y)

我猜这一定是由于 Vector 的 replicateM 的懒惰。实现,虽然很难看到,因为它是使用 streams 实现的.

我如何编写使用常量堆栈空间对大向量进行采样的代码?

最佳答案

monad-mersenne-random 没有什么明显的错误(没有看核心一iota),但值得注意的是,使用状态单子(monad)时一切正常:

import Control.Monad.State

...

        y      = evalState (U.replicateM dim (state $ \s -> randomInt64 s)) (pureMT 13) :: U.Vector Int64

结果是:
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3
$ ghc so.hs -fforce-recomp
[1 of 2] Compiling Control.Monad.Mersenne.Random ( Control/Monad/Mersenne/Random.hs, Control/Monad/Mersenne/Random.o )
[2 of 2] Compiling Main             ( so.hs, so.o )
Linking so ...
$ ./so
-7188968464842378225

编辑:

查看两个 monad 定义( StateTRand ),似乎唯一真正的区别在于元组的严格性。所以我尝试使用 Control.Monad.State.Strict啊哈!堆栈溢出返回。所以我猜这埋在Vector的replicateM代码类似于 foldr用于replicateM来自 base .这可以解释为什么您不希望序列严格。

关于haskell - 生成具有恒定堆栈空间的随机向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19946446/

相关文章:

haskell - "standardised"是什么意思,为什么是 Haskell 呢?

javascript - 使用序列为 arity 大于 1 的函数提供一元参数的正确方法是吗?

java - 再次检查一个列表中的所有内容,导致堆栈溢出

java - 创建对象而不导致堆栈溢出错误?

functional-programming - Monad 组合(续·状态)

Haskell 元组单子(monad)太严格了?

haskell - 意外的重叠实例错误

list - 如何提取Haskell列表中偶数位置的元素

Haskell Stack 和 C 库

c++ - 遍历 BST 时出现 Stackoverflow 异常