首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell的纯伪随机生成器,有很好的API?

问Haskell的纯伪随机生成器,有很好的API?
EN

Stack Overflow用户
提问于 2012-01-08 17:22:00
回答 3查看 1.5K关注 0票数 8

对于纯伪随机生成器(均匀双精度),推荐的Haskell包是什么?

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

也许是mwc-random?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-08 17:31:12

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

代码语言:javascript
复制
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。

票数 5
EN

Stack Overflow用户

发布于 2012-01-08 20:27:59

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

代码语言:javascript
复制
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函数获得类似的输出,该函数更简短、更通用(感谢ehird指出这一点):

代码语言:javascript
复制
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的split函数。让它工作的一种方法是将PureMT包装在newtype中,并为RandomGen类型类编写一个自定义的split实例,其中存在一个默认的MonadRandom实例。

代码语言:javascript
复制
import Control.Monad.Random
import System.Random.Mersenne.Pure64

getTenRandomDoubles :: Rand MyPureMT [Double]
getTenRandomDoubles = getRandoms >>= return . take 10

main = print $ evalRand getTenRandomDoubles g
  where g = MyPureMT $ pureMT 42


newtype MyPureMT = MyPureMT { unMyPureMT :: PureMT }
myPureMT = MyPureMT . pureMT

instance RandomGen MyPureMT where
  next  = nextMyPureMT
  split = splitMyPureMT

splitMyPureMT :: MyPureMT -> (MyPureMT, MyPureMT)
splitMyPureMT (MyPureMT g) = (myPureMT s, myPureMT s') where
  (s',g'') = randomWord64 g'
  (s ,g' ) = randomWord64 g

nextMyPureMT (MyPureMT g) = (s, MyPureMT g') where
  (s, g') = randomInt g
票数 8
EN

Stack Overflow用户

发布于 2012-01-11 01:05:54

cprng-aes包是一个特别好的包,它具有纯接口,也适用于密码应用程序,但仍保持高性能。

它提供了两个接口:一个是使用来自System.Random的类型类的确定性纯接口,另一个是使用来自Crypto-API包的类型类的强IO接口。

顺便说一下:我通常更喜欢mersenne-random包而不是mwc-random包。它们使用原始的Mersenne Twister算法,在我的基准测试中,它的性能比mwc-random高出很多。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8776520

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档