用MWC随机生成无限的Ints列表

时间:2014-10-19 08:16:53

标签: haskell random

我想写一个这样的函数:

myFnc :: Gen -> ([Int], Gen)

使用MWC Random。一般的想法是使用预定义的种子创建第一个Gen,然后以绝对纯粹的方式生成Int s和新Gen s的无限序列。

所以我开始尝试将种子Gen表示为Int。文档说我可以使用initialize函数来完成它。很好,让我们看看,它需要Word32 s的向量,所以尝试这个至少得到一个随机Int

import System.Random.MWC
import Data.Vector.Generic

rere :: IO ()
rere =
    do gen <- initialize (singleton 42)
       x   <- uniform gen :: Int
       print x

但它没有编译。错误:

Couldn't match expected type ‘Int’ with actual type ‘m0 a0’
    In a stmt of a 'do' block: x <- uniform gen :: Int
    In the expression:
      do { gen <- initialize (singleton 42);
           x <- uniform gen :: Int;
           print x }

我查看了文档,但它似乎与我非常简单的初始愿望相距甚远......

似乎我也不能使用uniform,因为它在monad中返回值,所以我真的不知道如何从所有这些东西中创建一个简单的Int s列表。< / p>


例如,以下是我要实现的内容,但System.Random

import System.Random

mkStdGen 5 -- first: that's how to create generator from given Int

myFnc :: StdGen -> ([Int], StdGen) -- second: desired function
myFnc g = (randoms g, fst . split $ g)

这很有效。

2 个答案:

答案 0 :(得分:1)

implemented a sample of this on FP Haskell Center。实施的核心是:

randoms :: (Variate a, PrimMonad m) => Gen (PrimState m) -> m [a]
randoms gen =
    loop
  where
    loop = return $ unsafeInlinePrim $ do
        x <- uniform gen
        xs <- loop
        return $! x : xs

请注意,它的类型签名与您要求的不同。特别是,没有&#34; split&#34;在mwc-random中。另外,在mwc-random中获取随机数本身就是一个可变的动作,所以我们需要生活在一些PrimMonad中以及使用不安全的内联。这可能是安全的,假设您从未使用过其他地方提供的Gen

但是,我认为您应该尝试重构您的程序以接受mwc-random的可变性质,或者切换到mersenne-random-pure64之类的纯随机数生成器。

答案 1 :(得分:0)

在System.Random.MWC中,&#34;制服&#34;返回一个类型&#34; m a&#34;但是你试图将它限制在Int。这就是你的错误所抱怨的。

x :: Int

在上一行。