用于Haskell的纯伪随机生成器具有良好的API?

时间:2012-01-08 09:22:00

标签: haskell random

对于纯伪随机生成器(均匀双打),推荐使用哪些Haskell包?

我首先对一个方便的API感兴趣,速度也会很好。

也许是mwc-random?

3 个答案:

答案 0 :(得分:8)

我喜欢mersenne-random-pure64套餐。例如,您可以像这样使用它从种子值生成无限懒惰的随机双精度流:

import Data.Word (Word64)
import Data.List (unfoldr)
import System.Random.Mersenne.Pure64

randomStream :: (PureMT -> (a, PureMT)) -> PureMT -> [a]
randomStream rndstep g = unfoldr (Just . rndstep) g

toStream :: Word64 -> [Double]
toStream seed = randomStream randomDouble $ pureMT seed

main = print . take 10 $ toStream 42

使用System.Random(randoms)

您可以使用内置randoms函数获得类似的输出,该函数更短且更通用(感谢ehird指出这一点):

import System.Random (randoms)
import System.Random.Mersenne.Pure64 (pureMT)

main = print . take 10 $ randomdoubles where
  randomdoubles :: [Double]
  randomdoubles = randoms $ pureMT 42

使其成为MonadRandom的实例

在阅读了MonadRandom后,我很好奇如何让PureMT作为它的一个实例。开箱即用它不起作用,因为PureMT没有实例化RandomGen的{​​{1}}功能。使其工作的一种方法是将split包装在PureMT中,并为newtype类型类编写自定义split实例,其中存在默认RandomGen实例。

MonadRandom

答案 1 :(得分:5)

标准System.Random具有纯接口。我建议将它包装在State g中(对于你正在使用的任何生成器 g )以避免线程化状态; state函数可以轻松地将next等函数转换为有状态操作:

next :: (RandomGen g) => g -> (Int, g)
state :: (s -> (a, s)) -> State s a
state next :: (RandomGen g) => State g Int

MonadRandom包基于State g接口,其中包含用于生成器函数的预先写好的包装器;我认为它很受欢迎。

请注意,您仍然可以使用此纯接口on the global RNG运行操作。为此,MonadRandom有evalRandIO

我认为你可以编写一个(孤儿)RandomGen实例来使用mwc-random。

答案 2 :(得分:2)

具有纯接口的特别好的软件包也适用于加密应用程序并且保持高性能,是cprng-aes软件包。

它提供了两个接口:使用System.Random中的类型类的确定性纯接口,以及使用Crypto-API包中的类型类的强IO接口。

作为旁注:我通常更喜欢mewne-random包而不是mwc-random。他们使用原始的Mersenne Twister算法,在我的基准测试中,mwc-random的表现优于大部分因素。