I don't think these answers are the whole picture. For my simulations I generate random numbers lazily and consume them strictly running in a smallish (1.1M on my macbook) space footprint.
Perhaps the remarks that random numbers can only exist in the IO monad refer to really random numbers but for pseudo-random numbers that is not the case and typically one wants to be able to reproduce results. Here's an example:
module Main (
main
) where
import qualified Data.Vector.Unboxed as V
import Data.Random.Source.PureMT
import Data.Random
import Control.Monad.State
nItt :: Int
nItt = 1000000000
gridSize :: Int
gridSize = 10
testData :: Int -> V.Vector Double
testData m =
V.fromList $
evalState (replicateM m (sample (uniform (0 :: Double) 1.0)))
(pureMT 2)
test = V.foldl (+) 0 (testData nItt)
main = putStrLn $ show test