使用随机生成N个随机数

时间:2014-10-17 20:53:55

标签: haskell random

我想使用randomR在一个范围之间生成N个随机数。

我知道还有其他方法可以实现这一目标,例如使用randomRs并在此代码中使用N,可以找到here

diff_select :: Int -> Int -> StdGen -> [Int]
diff_select n m = take n . nub . randomRs (1, m)

但我希望使用 randomR 并使用State monad。我不确定我在这个代码中犯了什么错误:

let fs = \s -> (randomR (0, 5) s, s)
let theState s = state (fs s)
let rep n ma = replicateM n (theState ma)
let res = runState (rep 3) (mkStdGen 4) -- Would like to use `get`

我该怎么做?

2 个答案:

答案 0 :(得分:5)

使用State monad生成随机数时,您希望状态值为生成器。在这种情况下,我们可以使用StdGen

type RandGen a = State StdGen a

然后你可以写出生成单个随机值的函数

getRandom :: Random a => RandGen a
getRandom = do
    gen <- get
    let (val, newGen) = random gen
    put newGen
    return val

现在,您可以使用此功能使用所有常用的Monad函数生成多个随机数,例如sequencemapM等。我们将让您实现此部分。最后,您所要做的就是执行代码:

> runState getRandom (mkStdGen 42) :: (Int, StdGen)

如果您想让它更容易,state函数具有以下类型:

state :: MonadState s m => (s -> (a, s)) -> m a

random的类型为

random :: (Random a, RandomGen g) => g -> (a, g)

注意sg似乎排在这里的方式?您实际上可以通过

替换getRandom
getRandom :: Random a => RandGen a
getRandom = state random

所有艰苦的工作都是为你完成的。

答案 1 :(得分:0)

我想你想要:

let res = runState (rep 3) (mkStdGen 4)

你写的内容相当于:

runState (rep 3 (mkStdGen 4))

......这是不一样的。