哈斯克尔随机生成(Haskell Random Generation)

2019-09-18 03:53发布

可能有人形容以下类型的构造和功能是如何工作的?

type Rand a = State StdGen a  

getRandom :: (Random a) => Rand a
getRandom = get >>= (\r -> let (a,g) = random r in (put g) >> (return a))

runRand :: Int -> Rand a -> a
runRand n r = evalState r $ mkStdGen n

runRandIO :: Rand a -> IO a
runRandIO r = randomIO >>= (\rnd -> return $ runRand rnd r)

getRandoms :: (Random a) => Int -> Rand [a]
getRandoms n = mapM (\_ -> getRandom) [1..n]

Answer 1:

让我们从头开始:

type Rand a = State StdGen a

这行告诉你, Rand a是对一种类型的代名词State类型,其状态由给定StdGen ,其最终的价值型的a 。 这将被用来存储每个请求之间的随机数生成器的状态为一随机数。

对于代码getRandom可以转换成做记号:

getRandom :: (Random a) => Rand a
getRandom = do
  r <- get                   -- get the current state of the generator
  let (a,g) = random r in do -- call the function random :: StdGen -> (a, StdGen)
    put g                    -- store the new state of the generator
    return a                 -- return the random number that was generated

所述runRand函数接受一个初始种子n和值r型的Rand a (其中,记住,仅仅是一个同义词State StdGen a )。 它创建一个新的发电机mkStdGen n和饲料它evalState r 功能evalState只计算一个返回值State sa型,忽视的状态。

同样,我们可以将runRandIOdo记号:

runRandIO :: Rand a -> IO a
runRandIO r = do
  rnd <- randomIO        -- generate a new random number using randomIO
  return (runRand rnd r) -- use that number as the initial seed for runRand

最后, getRandoms花费数n表示要生成的随机值的数量。 它建立一个列表[1..n]和适用getRandom到列表中。 需要注意的是在实际值[1..n]未使用(你可以告诉,因为lambda函数开头\_ -> ... )。 该名单只是那里有正确数量的元素的东西。 由于getRandom返回一个monadic值,我们使用mapM映射在所述列表中,这会导致状态(即StdGen )要通过每个调用的正确螺纹getRandom



Answer 2:

基本想法很简单 - 创造伪随机数,你需要维护函数调用之间的一些状态。 因此,类型Rand a的定义是指“ a有需要的随机性国家一起”。

国家将使用存储State单子 。 这提供了两个主要actions-- getput ,这不,他们的声音究竟是什么样子。 所以getRandom刚刚抬头的当前状态,然后调用random函数。 该函数返回两个值:随机值和新的状态。 然后你只需put新的状态和包装所产生的价值。

runRand让你解开给予种子“随机”值。 evalState让你执行一个有状态计算(也就是类型的值State sa或者,在这种情况下, Rand a )给定的初始状态,然后就放弃最终状态,只给你结果。 因此,这允许您运行Rand a给定的种子,只返回结果值。 该值可以只输入了a ,而不是Rand a因为它总是给你相同的结果为相同的种子。

runRandomIO只是做同样的事情,除了基于种子关在IO一些全局状态得到。

getRandoms只是让你列表Rand a致电值getRandom为的每一个元素[1..n]列表(忽略实际数量)。



文章来源: Haskell Random Generation