theStdGen unsafePerformIO

Why does theStdGen require unsafePerformIO? I recompiled the Random module with theStdGen :: IO (IORef StdGen) theStdGen = do rng <- mkStdRNG 0 newIORef rng The implementations of a few functions needed to change slightly (to extract the IORef from IO), but no other type signatures needed changing, and nothing blew up.

You might get more answers to this sort of question on the
haskell-cafe list. Even there, I think you might need to ask whoever
the authors were for a question like this :-)
On Sun, Jan 9, 2011 at 9:55 AM, John Smith
Why does theStdGen require unsafePerformIO? I recompiled the Random module with
theStdGen :: IO (IORef StdGen) theStdGen = do rng <- mkStdRNG 0 newIORef rng
The implementations of a few functions needed to change slightly (to extract the IORef from IO), but no other type signatures needed changing, and nothing blew up.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Sun, Jan 09, 2011 at 05:55:41PM +0200, John Smith wrote:
Why does theStdGen require unsafePerformIO? I recompiled the Random module with
theStdGen :: IO (IORef StdGen) theStdGen = do rng <- mkStdRNG 0 newIORef rng
The implementations of a few functions needed to change slightly (to extract the IORef from IO), but no other type signatures needed changing, and nothing blew up.
With your definition, theStdGen is a computation that gives you a *new*, *different* IORef (containing yet another generator initialized with a seed of zero) every time you call it. The original definition with unsafePerformIO generates a single, global IORef which is accessed by every subsequent call to getStdGen. -Brent

On 09/01/2011 18:16, Brent Yorgey wrote:
With your definition, theStdGen is a computation that gives you a *new*, *different* IORef (containing yet another generator initialized with a seed of zero) every time you call it. The original definition with unsafePerformIO generates a single, global IORef which is accessed by every subsequent call to getStdGen.
How does it do this?

Because unsafePerformIO returns a pure value 'a', GHC only computes it once and then reuses it later (it's also why when you do this you need to make sure you tell GHC not to inline the computation, which will obviously change the semantics.) Cheers, Edward

On 09/01/2011 19:40, Edward Z. Yang wrote:
Because unsafePerformIO returns a pure value 'a', GHC only computes it once and then reuses it later (it's also why when you do this you need to make sure you tell GHC not to inline the computation, which will obviously change the semantics.)
theStdGen doesn't have NOINLINE. Is the pragma on unsafeDupablePerformIO sufficient for any caller of unsafePerformIO?
participants (4)
-
Antoine Latter
-
Brent Yorgey
-
Edward Z. Yang
-
John Smith