
It's more like "Seed → [a]". IO is not really needed here. You're absolutely right. I stand corrected.
1. One may want to generate values of different types and/or distibutions. Yes, I saw this limitation before. But you can just generate one infinite list (and then one seed) per distribution, right? Or could you generate something homomorphic to [(Random a) => a]? (Each element would then basically be a closure containing the current Seed)
2. No way to make snapshot of generator state. You mean the current seed? You don't need to access that if you only consume PRNs from the infinite list(s), and that during the whole program.
3. Laziness overhead. It may be significant if you try to squeeze last bit of performance. I'm afraid that if you're frightened by the laziness overhead then you won't use Haskell. I'm kidding, but it's just I don't picture the overhead being so huge in that case. What so big would the runtime need to keep in memory except for the closure that generates the infinite list?
2012/2/10 Aleksey Khudyakov
On 10.02.2012 18:38, Yves Parès wrote:
I just thought about something: basically all these APIs provides a "IO [a]" (where a is a randomly generable type) function. Is there a problem with the approach that is to rely on lazy evaluation to pass to pure code (either explicitely or through State) the infinite list generated in IO and consume its head each time we need a random value? Because there is no issue such as resource holding, like in the case of file reading and enumerators, which would make lazy IO a not so good approach...
It's more like "Seed → [a]". IO is not really needed here. I can see following problems. None are real showstoppers (except maybe 2)
1. One may want to generate values of different types and/or distibutions. This is easily solved by state monad. But I can't see advantage over wrapped ST.
2. No way to make snapshot of generator state.
3. Laziness overhead. It may be significant if you try to sqeeze last bit of performance.