对于纯伪随机生成器(均匀双打),推荐使用哪些Haskell包?
我首先对一个方便的API感兴趣,速度也会很好。
也许是mwc-random?
答案 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的表现优于大部分因素。