
On Fri, Jan 29, 2010 at 12:59:30PM +0200, Gabi wrote:
I think the problem is in "rs <- sequence (replicate n isRandIn)" - But I don't know how to get around it (how do I get a lazy sequence of rs? Is it the problem anyway?)
First of all, we don't like to be inside IO just for getting random numbers. It is better to write, for example, type Point = (Double, Double) randPoint :: StdGen -> (Point, StdGen) randPoint gen = let (x, gen') = randomR (0,1) gen (y, gen'') = randomR (0,1) gen' in ((x,y),gen'') and then thread the generator yourself randPoints :: StdGen -> [Point] randPoints gen = let (p,gen') = randPoint gen in p : randPoints gen' -- lazy! To use those functions, something like import Control.Applicative ((<$>)) inCirc :: Point -> Bool inCirc = ... calcPi :: Int -> [Point] -> Double calcPi n pts = let s = length $ filter inCirc $ take n pts in 4 * fromIntegral s / fromIntegral n main = do pi <- calcPi 10000 . randPoints <$> newStdGen print pi I haven't tested performance, but it shouldn't be worse :), and it's cleaner and more idiomatic. To be even clearer you could use MonadRandom[1] which encapsulates the passing of StdGen between computations. [1] http://hackage.haskell.org/package/MonadRandom However System.Random (used by MonadRandom as well) is known to be very very very very slow. If you want more performance then you should use one of the other PRNG libraries on Hackage: http://hackage.haskell.org/package/mwc-random http://hackage.haskell.org/package/mersenne-random http://hackage.haskell.org/package/gsl-random The reason why System.Random is slow is because it must support 'split', which none of the packages above support. HTH, -- Felipe.