System.Random is way too lazy
randomRs is too lazy, generates lists of large lazy-state thunks, rather than lists of strict values.
Test program is attached.
Also, randomIO is too lazy, and builds up huge thunks. Using (randomIO >>= evaluate) is fine, however.
Fails with stack overflow:
rs <- replicateM 1000000 evaluate :: IO [Int]
print $ last rs
Works:
rs <- replicateM 1000000 (evaluate =<< randomIO) :: IO [Int]
print $ last rs