Haskell monad: IO [Double] to [IO Double]
haskell, io, monads, random
Solution
If you get a segmentation fault error, and you didn't use the FFI or any functions with `unsafe` in their name, that's not unsurprising, in any situation! It means there's a bug with either GHC, or a library you're using is doing something unsafe.
Printing out an infinite list of `Double`s with `mapM_ print` is perfectly fine; the list will be processed incrementally and the program should run with constant memory usage. I suspect there is a bug in the `System.Random.Mersenne` module you're using, or a bug the C library it's based on, or a problem with your computer (such as faulty RAM).1 Note that `newMTGen` comes with this warning:
Due to the current SFMT library being vastly impure, currently only a single generator is allowed per-program. Attempts to reinitialise it will fail.
You might be better off using the provided global `MTGen` instead.
That said, you can't convert `IO [Double]` into `[IO Double]` in that way; there's no way to know how long the resulting list would be without executing the `IO` action, which is impossible, since you have a pure result (albeit one that happens to contain `IO` actions). For infinite lists, you could write:
desequence :: IO [a] -> [IO a]
desequence = desequence' 0
where
desequence n m = fmap (!! n) m : desequence (n+1) m
But every time you execute an action in this list, the `IO [a]` action would be executed again; it'd just discard the rest of the list.
The reason `randoms` can work and return an infinite list of random numbers is because it uses lazy IO with `unsafeInterleaveIO`. (Note that, despite the "unsafe" in the name, this one can't cause segfaults, so something else is afoot.)
1 Other, less likely possibilities include a miscompilation of the C library, or a bug in GHC.
Problem
Consider the following code that is supposed to print out random numbers: ``` import System.Random.Mersenne main = do g <- (newMTGen Nothing) xs <- (randoms g) :: IO [Double] mapM_ print xs ``` When run, I get a segmentation fault error. That is unsurprising, since the function 'randoms' produces an infinite list. Suppose I wanted to print out only the first ten values of xs. How could I do that? xs has type IO [Double], and I think I want a variable of type [IO Double]. What operators exist to convert between the two.