使用randomR生成N个随机数

One*_*ion 2 random haskell

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

我知道有其他方法可以实现这一点,例如randomRs在此代码中使用和获取N,可在此处找到:

diff_select :: Int -> Int -> StdGen -> [Int]
diff_select n m = take n . nub . randomRs (1, m)
Run Code Online (Sandbox Code Playgroud)

但我想使用randomR和使用Statemonad.我不确定我在这个代码中犯了什么错误:

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`
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

bhe*_*ilr 5

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

type RandGen a = State StdGen a
Run Code Online (Sandbox Code Playgroud)

然后,您可以编写用于生成单个随机值的函数

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

现在,你可以用它来生成使用所有常用的多个随机数Monad的功能,如sequence,mapM等我就让你实现这一部分.最后,您所要做的就是执行代码:

> runState getRandom (mkStdGen 42) :: (Int, StdGen)
Run Code Online (Sandbox Code Playgroud)

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

state :: MonadState s m => (s -> (a, s)) -> m a
Run Code Online (Sandbox Code Playgroud)

random有类型

random :: (Random a, RandomGen g) => g -> (a, g)
Run Code Online (Sandbox Code Playgroud)

请注意这里s和如何g排队?实际上,你可以替换getRandom通过

getRandom :: Random a => RandGen a
getRandom = state random
Run Code Online (Sandbox Code Playgroud)

所有的辛勤工作都是为你完成的.

  • 好的,那么你怎么能写一些非常类似于我使用`randomR`的东西呢?什么是`randomR`的类型? (2认同)