Haskell和随机数字 [英] Haskell and random numbers

查看:92
本文介绍了Haskell和随机数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我需要一个返回整数的随机列表(Rand [[Int])的方法,所以,我定义了一个类型: type Rand a = StdGen - > (a,StdGen)
我可以产生 Rand IO Integer Rand [IO Integer] (returnR lst):: StdGen - >([IO Integer],StdGen))。任何提示如何产生 Rand [[Int]]

解决方案

如何避免 IO 取决于它首先引入的原因。虽然伪随机数发生器本质上是面向状态的,但没有理由需要涉及 IO



I我会猜测并说您正在使用 newStdGen getStdGen 来获得您的初始PRNG。如果是这样的话,那么就没有办法完全逃避 IO 。您可以直接使用 mkStdGen 来播种PRNG,但请记住,相同的种子会产生相同的随机数字序列。



更可能的是,你想要做的是在 IO 中获得一个PRNG,然后将它作为参数传递给一个纯函数。当然,整个事情仍然会被封装在 IO 中,但是中间计算并不需要它。这里有一个简单的例子给你的想法:

$ p $ import System.Random

类型Rand a = StdGen - > (a,StdGen)

getPRNG = do
rng< - newStdGen
let x = usePRNG rng
print x

usePRNG: :StdGen - >在[x,y]中$ [

usePRNG rng = let(x,rng')= randomInts 5 rng
(y,_)= randomInts 10 b
randomInts :: Int - > Rand [Int]
randomInts 0 rng =([],rng)
randomInts n rng = let(x,rng')= next rng
(xs,rng'')= randomInts n - 1)rng'
in(x:xs,rng'')

您可能会注意到使用PRNG的代码变得非常难看,因为不断来回传递当前值。它也可能容易出错,因为很容易意外地重用旧值。如上所述,使用相同的PRNG值将给出相同的数字序列,这通常不是您想要的。这两个问题都是使用 State monad有意义的一个很好的例子 - 这里正在讨论主题,但您可能希望继续研究它。


I've been messing with Haskell few days and stumbled into a problem.

I need a method that returns a random list of integers ( Rand [[Int]] ).

So, I defined a type: type Rand a = StdGen -> (a, StdGen). I was able to produce Rand IO Integer and Rand [IO Integer] ( (returnR lst) :: StdGen -> ([IO Integer], StdGen) ) somehow. Any tips how to produce Rand [[Int]]?

解决方案

How to avoid the IO depends on why it's being introduced in the first place. While pseudo-random number generators are inherently state-oriented, there's no reason IO needs to be involved.

I'm going to take a guess and say that you're using newStdGen or getStdGen to get your initial PRNG. If that's the case, then there's no way to completely escape IO. You could instead seed the PRNG directly with mkStdGen, keeping in mind that the same seed will result in the same "random" number sequence.

More likely, what you want to do is get a PRNG inside IO, then pass that as an argument to a pure function. The entire thing will still be wrapped in IO at the end, of course, but the intermediate computations won't need it. Here's a quick example to give you the idea:

import System.Random

type Rand a = StdGen -> (a, StdGen)

getPRNG = do
    rng <- newStdGen
    let x = usePRNG rng
    print x

usePRNG :: StdGen -> [[Int]]
usePRNG rng = let (x, rng') = randomInts 5 rng
                  (y, _) = randomInts 10 rng'
              in [x, y]

randomInts :: Int -> Rand [Int]
randomInts 0 rng = ([], rng)
randomInts n rng = let (x, rng') = next rng
                       (xs, rng'') = randomInts (n - 1) rng'
                   in (x:xs, rng'')

You might notice that the code using the PRNG gets pretty ugly due to passing the current value back and forth constantly. It's also potentially error prone, since it'd be easy to accidentally reuse an old value. As mentioned above, using the same PRNG value will give the same sequence of numbers, which is usually not what you want. Both problems are a perfect example of where it makes sense to use a State monad--which is getting off topic here, but you may want to look into it next.

这篇关于Haskell和随机数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆