Up vote 2 down vote favorite share g+ share fb share tw.
I would like to generate infinite stream of numbers with Rand monad from System.Random.MWC.Monad. If only there would be a MonadFix instance for this monad, or instance like this: instance (PrimMonad m) => MonadFix m where ... then one could write: runWithSystemRandom (mfix (\ xs -> uniform >>= \x -> return (x:xs))) There isn't one though. I was going through MonadFix docs but I don't see an obvious way of implementing this instance.
Haskell random monads link|improve this question edited Mar 19 '11 at 22:46 asked Mar 19 '11 at 22:15Tener1,066617 100% accept rate.
– FUZxxl Mar 20 '11 at 9:32 I think you rather meant sequence (repeat uniform). Well, the problem is the code like runWithSystemRandom (asRandST $ sequence (repeat uniform)) isn't lazy in the output, i.e. Will never produce single digit before it finishes the computation, which is infinite.
– Tener Mar 21 '11 at 0:06 Yes, you're right. And this is indeed a problem. – FUZxxl Mar 21 '11 at 15:01.
The problem is that MWS is built on the "primitive" package which abstracts only IO and strict (Control.Monad.ST" rel="nofollow">Control.Monad.ST" rel="nofollow">Control.Monad.ST" rel="nofollow">Control.Monad.ST. ST s). It does not also abstract lazy (Control.Monad.ST" rel="nofollow">Control.Monad.ST" rel="nofollow">Control.Monad.ST" rel="nofollow">Control.Monad.ST.Lazy.
ST s). Perhaps one could make instances for "primitive" to cover lazy ST and then MWS could be lazy. UPDATE: I can make this work using Control.Monad.ST" rel="nofollow">Control.Monad.ST" rel="nofollow">Control.Monad.ST" rel="nofollow">Control.Monad.ST.
Lazy by using strictToLazyST: module Main where import Control. Monad(replicateM) import qualified Control.Monad. ST as S import qualified Control.Monad.ST" rel="nofollow">Control.Monad.ST" rel="nofollow">Control.Monad.ST" rel="nofollow">Control.Monad.ST.
Lazy as L import qualified System.Random. MWC as A foo :: Int -> L. ST s Int foo I = do rest S.
ST s Int splam = A. UniformR (0,100) getS :: Int -> S. ST s Int getS n = do gen L.
ST s Int getL n = do gen L. ST s Int makeLots gen = do x >= makeLots) :: Int print (take 10 inf3).
Initial seed would be supplied from outside, i.e. /dev/random or time(0) or anything. – Tener Mar 21 '11 at 23:32 So modify inf3: pass the seed into createLazy and then L.
RunST on your variant of makeLots will return a pure_infinite_lazy_list of random values made with MWC. No Rand monad needs to be imported or used. – Chris Kuklewicz Mar 22 '11 at 0:33.
You can write a MonadFix instance. However, the code will not generate an infinite stream of distinct random numbers. The argument to mfix is a function that calls uniform exactly once.
When the code is run, it will call uniform exactly once, and create an infinite list containing the result. You can try the equivalent IO code to see what happens: import System. Random import Control.Monad.
Fix main = print . Take 10 = randomIO >>= (\x -> return (x : xs :: Int))) It seems that you want to use a stateful random number generator, and you want to run the generator and collect its results lazily. That isn't possible without careful use of unsafePerformIO.
Unless you need to produce many random numbers quickly, you can use a pure RNG function such as randomRs instead.
Running the generator and collecting the results lazily could be accomplished with the ST monad, or worst-case, unsafeInterleaveIO, rather than unsafePerformIO. – John L Mar 20 '11 at 14:28 @John An ST random number generator computes all of its output eagerly when its output is demanded. When the output is an infinite list, eager evaluation doesn't work so well.
– Heatsink Mar 20 '11 at 16:51.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.