我想在Gen (ST {..}
monad之外处理/存储随机生成器(ST
),但我找不到该怎么做。
我正在为一些大量使用随机的模拟工作。 通过分析,我知道随机数占据处理时间的50%以上。
要创建随机数,我使用mwc-random和SFMT
由于速度问题,我主要使用SFMT
但是,与SFMT
,mwc-random
相比,我需要更丰富的界面(例如normal
,bernoulli
,..)。
在基准和读取代码之后,我了解mwc-random
在SFMT
monad上使用时ST
并不比SFMT
慢。
(IO
上的MWC
< ST
MWC
<< IO
SFMT
< ST
{{{{} {MWC
1}})
所以,我想在ST
monad上制作和处理ST
随机生成器。
但是,我无法将ST
monad中的此生成器与其他STRef
内容相同(例如ST
)。
有没有办法在STRef
monad 安全地之外处理/存储这个随机生成器?
我尝试使用import qualified System.Random.MWC as MWC
import GHC.Prim
import Control.Monad
data World = World { randomGen :: MWC.Gen RealWorld }
initWorld = do gen <- MWC.create
return $ World gen
something gen = do num <- MWC.uniformR (1,100) gen :: IO Int
print num
main = do world <- initWorld
replicateM_ 100 $ something (randomGen world)
或其他内容从许多软件包/代码中学习,但我无法理解。
我在模拟中使用随机生成器就像这样。
import qualified System.Random.MWC as MWC
import Control.Monad
import Control.Monad.Primitive
import Control.Monad.ST
data World s = World { randomGen :: MWC.Gen (PrimState (ST s))}
initWorld :: ST s (World s)
initWorld = do gen <- MWC.create
return $ World gen
something gen = do
let num :: Int
num = runST $ do num <- MWC.uniformR (1,100) gen
return num
print num
main = do let world = runST initWorld
replicateM_ 100 $ something (randomGen world)
但是,这段代码不起作用。
something
我想重写此代码以使用Gen (PrimState (ST s))
。
我是否需要定义/重写数据结构或执行其他操作?
有更聪明的方法吗?
ST
)来重现结果
所以,我不想生产ad-hoc随机生成器。 86 Query select * from blacklist where mobile_token = 'b'
86 Query SHOW WARNINGS
86 Query select @@session.tx_read_only
86 Query update mydatabase.blacklist set email=null, iban=null, mobile_token=null, nif=null where blacklist_id=1
86 Query SHOW WARNINGS
86 Query commit
86 Query SET autocommit=1
86 Query SET autocommit=1
86 Query set session transaction read write
monad上进行。答案 0 :(得分:1)
你不应该试图在ST monad之外操纵发生器。由于runST
的类型,试图使用生活内容&#34;内部&#34;国家线程&#34;外部&#34;这是非荒谬的。想象一下,你有一个以下类型的函数(这是你要写的函数):
something :: MWC.Gen s -> Int
something gen = runST ...
为了生成随机数,必须使用Gen
内的数据进行一些有状态计算。这些计算将在何时完成?如果有的话,他们会完成多少次?最重要的是 - something
如何生成随机数 - 毕竟它是一个纯函数,所以它必须为相同的输入返回相同的值。
相反,你应该绕过状态,并在结尾处调用runST
:
something :: MWC.Gen s -> ST s Int
something = MWC.uniformR (1,100)
main = mapM_ print $ runST $ do
w0 <- initWorld
replicateM 100 (something $ randomGen w0)