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:

  1. i need handle random generator (like gen (primstate (st s))) reproduce results.
    so, not want produce ad-hoc random generator.
  2. 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 on st monad.
  3. 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

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -