title: How to store ST monad thing?
body: <p>I want to handle/store random generator(<code>Gen (ST {..}</code>) outside of <code>ST</code> monad, but I couldn't find how to do.</p>
  
  <h1>Background</h1>
  
  <p>I'm under working for some simulation which uses random heavily.
  With profiling, I knew that make random numbers takes more than 50% of process time.</p>
  
  <p>To make random number, I use <a href="http://hackage.haskell.org/package/mwc-random" rel="nofollow">mwc-random</a> and <a href="http://hackage.haskell.org/package/sfmt" rel="nofollow">SFMT</a>.<br>
  Because of speed issue, I mainly use <code>SFMT</code>.<br>
  However, comeparing with <code>SFMT</code>, <code>mwc-random</code> have richer interfaces that I need(like <code>normal</code>, <code>bernoulli</code>, ..).</p>
  
  <p>After benchmark and read codes, I understand that <code>mwc-random</code> is not too slow than <code>SFMT</code> when it is used on <code>ST</code> monad.<br>
  (<code>SFMT</code> on <code>IO</code> &lt; <code>MWC</code> on <code>ST</code> &lt;&lt; <code>MWC</code> on <code>IO</code> &lt; <code>SFMT</code> on <code>ST</code>)<br>
  So, I want to make and handle <code>MWC</code> random generator on <code>ST</code> monad. 
  However, I cannot take this generator out from <code>ST</code> monad as same as other <code>ST</code> things(e.g. <code>STRef</code>).</p>
  
  <h1>Problem</h1>
  
  <p>Is there any way to handle/store this random generator outside of <code>ST</code> monad <b>safely</b>?</p>
  
  <p>I tried to study from many packages/codes with <code>STRef</code> or something others, but I couldn't figure it out.</p>
  
  <h1>Example</h1>
  
  <p>I use random generator in the simulation like this way.</p>
  
  <pre><code>import qualified System.Random.MWC as MWC
  import GHC.Prim
  import Control.Monad
  
  data World = World { randomGen :: MWC.Gen RealWorld }
  
  initWorld = do gen &lt;- MWC.create
                 return $ World gen
  
  something gen = do num &lt;- MWC.uniformR (1,100) gen :: IO Int
                     print num
  
  main = do world &lt;- initWorld
            replicateM_ 100 $ something (randomGen world)
  </code></pre>
  
  <p>But, this code does not works.</p>
  
  <pre><code>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 &lt;- MWC.create
                 return $ World gen
  
  something gen = do
      let num :: Int
          num = runST $ do num &lt;- MWC.uniformR (1,100) gen
                           return num
      print num
  
  main = do let world = runST initWorld
            replicateM_ 100 $ something (randomGen world)
  </code></pre>
  
  <p>I want rewrite this code to work with <code>something</code>.
  Do I need to define/rewrite data structure or do something other?
  Is there more smart way?</p>
  
  <h2>Points:</h2>
  
  <ol>
  <li>I need to handle a random generator (like <code>Gen (PrimState (ST s))</code>) to reproduce results.<br>
  So, I do not want to produce ad-hoc random generator.</li>
  <li>I do not wants to save/restore seed. It has too big overhead.
  (save/restore seed takes x12~15 time more than generate one random number)<br>
  It is slower than using on IO monad, so I do not need to do on <code>ST</code> monad.</li>
  <li>I do not want to use unsafe* functions.</li>
  </ol>