haskell - How to store ST monad thing? -
i want handle/store random generator(gen (st {..}
) outside of st
monad, couldn't find how do.
background
i'm under working simulation uses random heavily. profiling, knew make random numbers takes more 50% of process time.
to make random number, use mwc-random , sfmt.
because of speed issue, use sfmt
.
however, comeparing sfmt
, mwc-random
have richer interfaces need(like normal
, bernoulli
, ..).
after benchmark , read codes, understand mwc-random
not slow sfmt
when used on st
monad.
(sfmt
on io
< mwc
on st
<< mwc
on io
< sfmt
on st
)
so, want make , handle mwc
random generator on st
monad. however, cannot take generator out st
monad same other st
things(e.g. stref
).
problem
is there way handle/store random generator outside of st
monad safely?
i tried study many packages/codes stref
or others, couldn't figure out.
example
i use random generator in simulation way.
import qualified system.random.mwc mwc import ghc.prim import control.monad data world = world { randomgen :: mwc.gen realworld } initworld = gen <- mwc.create return $ world gen gen = num <- mwc.uniformr (1,100) gen :: io int print num main = world <- initworld replicatem_ 100 $ (randomgen world)
but, code not works.
import qualified system.random.mwc 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 = gen <- mwc.create return $ world gen gen = let num :: int num = runst $ num <- mwc.uniformr (1,100) gen return num print num main = let world = runst initworld replicatem_ 100 $ (randomgen world)
i want rewrite code work something
. need define/rewrite data structure or other? there more smart way?
points:
- i need handle random generator (like
gen (primstate (st s))
) reproduce results.
so, not want produce ad-hoc random generator. - i not wants save/restore seed. has big overhead. (save/restore seed takes x12~15 time more generate 1 random number)
slower using on io monad, not need onst
monad. - i not want use unsafe* functions.
you shouldn't try manipulate generator outside of st monad. because of type of runst
, trying use things live "inside" state thread "outside" of non-nonsensical. imagine had function of following type (which function trying write):
something :: mwc.gen s -> int gen = runst ...
in order generate random numbers, stateful computations must done data inside of gen
. @ point computations done? how many times done, if @ all? importantly - how can something
generating random numbers - pure function, after all, must return same value same input.
instead, should thread state along, , call runst
@ end:
something :: mwc.gen s -> st s int = mwc.uniformr (1,100) main = mapm_ print $ runst $ w0 <- initworld replicatem 100 (something $ randomgen w0)
Comments
Post a Comment